From 83bda08d301e205b184ef5fcd1d377923b0dc0a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Sep 2023 20:39:35 +0000 Subject: [PATCH 01/44] Bump numpy from 1.25.2 to 1.26.0 Bumps [numpy](https://github.com/numpy/numpy) from 1.25.2 to 1.26.0. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](https://github.com/numpy/numpy/compare/v1.25.2...v1.26.0) --- updated-dependencies: - dependency-name: numpy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index b81f6c38f06..894c0f66b00 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ -numpy==1.25.2 +numpy==1.26.0 opencv_python==4.8.1.78 mediapipe==0.10.5 From fd1fe5689c87efd1125c09266edd3d155f64d595 Mon Sep 17 00:00:00 2001 From: Coding Capricorn Date: Tue, 3 Oct 2023 11:37:48 +0100 Subject: [PATCH 02/44] Create TowerOfHanoi.py Tower of Hanoi using Python --- TowerOfHanoi.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 TowerOfHanoi.py diff --git a/TowerOfHanoi.py b/TowerOfHanoi.py new file mode 100644 index 00000000000..af89032fce0 --- /dev/null +++ b/TowerOfHanoi.py @@ -0,0 +1,14 @@ +# Recursive Python function to solve the tower of hanoi -- + +def TowerOfHanoi(n , source, destination, auxiliary): + if n==1: + print ("Move disk 1 from source",source,"to destination",destination) + return + TowerOfHanoi(n-1, source, auxiliary, destination) + print ("Move disk",n,"from source",source,"to destination",destination) + TowerOfHanoi(n-1, auxiliary, destination, source) + +# Driver code +n = 4 +TowerOfHanoi(n,'A','B','C') +# A, C, B are the name of rods From 9a66c30e0606595b9f288573239273aeaba46b57 Mon Sep 17 00:00:00 2001 From: Abhay-1552 Date: Wed, 4 Oct 2023 16:00:19 +0530 Subject: [PATCH 03/44] Wikipedia Scraping BeautifulSoup and Flask Framework --- Wikipdedia/flask_rendering.py | 27 +++++++++++ Wikipdedia/main.py | 16 +++++++ Wikipdedia/practice_beautifulsoap.py | 69 ++++++++++++++++++++++++++++ Wikipdedia/static/js/output.js | 9 ++++ Wikipdedia/template/index.html | 42 +++++++++++++++++ Wikipdedia/template/output.html | 35 ++++++++++++++ 6 files changed, 198 insertions(+) create mode 100644 Wikipdedia/flask_rendering.py create mode 100644 Wikipdedia/main.py create mode 100644 Wikipdedia/practice_beautifulsoap.py create mode 100644 Wikipdedia/static/js/output.js create mode 100644 Wikipdedia/template/index.html create mode 100644 Wikipdedia/template/output.html diff --git a/Wikipdedia/flask_rendering.py b/Wikipdedia/flask_rendering.py new file mode 100644 index 00000000000..05c6d7494bf --- /dev/null +++ b/Wikipdedia/flask_rendering.py @@ -0,0 +1,27 @@ +from flask import Flask, render_template, request +import practice_beautifulsoap as data + +app = Flask(__name__, template_folder='template') + + +@app.route('/', methods=["GET", "POST"]) +def index(): + languages = data.lang() + return render_template('index.html', languages=languages) + + +@app.route("/display", methods=["POST"]) +def output(): + if request.method == "POST": + entered_topic = request.form.get("topic") + selected_language = request.form.get("language") + + soup_data = data.data(entered_topic, selected_language) + soup_image = data.get_image_urls(entered_topic) + + return render_template('output.html', heading=entered_topic.upper(), data=soup_data, + url=soup_image, language=selected_language) + + +if __name__ == "__main__": + app.run(debug=True) diff --git a/Wikipdedia/main.py b/Wikipdedia/main.py new file mode 100644 index 00000000000..5596b44786f --- /dev/null +++ b/Wikipdedia/main.py @@ -0,0 +1,16 @@ +# This is a sample Python script. + +# Press Shift+F10 to execute it or replace it with your code. +# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings. + + +def print_hi(name): + # Use a breakpoint in the code line below to debug your script. + print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint. + + +# Press the green button in the gutter to run the script. +if __name__ == '__main__': + print_hi('PyCharm') + +# See PyCharm help at https://www.jetbrains.com/help/pycharm/ diff --git a/Wikipdedia/practice_beautifulsoap.py b/Wikipdedia/practice_beautifulsoap.py new file mode 100644 index 00000000000..00beb87fc44 --- /dev/null +++ b/Wikipdedia/practice_beautifulsoap.py @@ -0,0 +1,69 @@ +from bs4 import BeautifulSoup +import requests + +language_symbols = {} + + +def lang(): + try: + response = requests.get("https://www.wikipedia.org/") + response.raise_for_status() + soup = BeautifulSoup(response.content, 'html.parser') + + for option in soup.find_all('option'): + language = option.text + symbol = option['lang'] + language_symbols[language] = symbol + + return list(language_symbols.keys()) + + except requests.exceptions.RequestException as e: + print("Error fetching language data:", e) + return [] + + +def data(selected_topic, selected_language): + symbol = language_symbols.get(selected_language) + + try: + url = f"https://{symbol}.wikipedia.org/wiki/{selected_topic}" + data_response = requests.get(url) + data_response.raise_for_status() + data_soup = BeautifulSoup(data_response.content, 'html.parser') + + main_content = data_soup.find('div', {'id': 'mw-content-text'}) + filtered_content = "" + + if main_content: + for element in main_content.descendants: + if element.name in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']: + filtered_content += "\n" + element.get_text(strip=True).upper() + "\n" + + elif element.name == 'p': + filtered_content += element.get_text(strip=True) + "\n" + + return filtered_content + + except requests.exceptions.RequestException as e: + print("Error fetching Wikipedia content:", e) + return "Error fetching data." + + +def get_image_urls(query): + try: + search_url = f"https://www.google.com/search?q={query}&tbm=isch" + image_response = requests.get(search_url) + image_response.raise_for_status() + image_soup = BeautifulSoup(image_response.content, 'html.parser') + + image_urls = [] + for img in image_soup.find_all('img'): + image_url = img.get('src') + if image_url and image_url.startswith("http"): + image_urls.append(image_url) + + return image_urls[0] + + except requests.exceptions.RequestException as e: + print("Error fetching image URLs:", e) + return None diff --git a/Wikipdedia/static/js/output.js b/Wikipdedia/static/js/output.js new file mode 100644 index 00000000000..5c360de488e --- /dev/null +++ b/Wikipdedia/static/js/output.js @@ -0,0 +1,9 @@ +function validateForm() { + var language = document.getElementById("language").value; + + if (language === "Select") { + alert("Please select a language."); + return false; + } +} + diff --git a/Wikipdedia/template/index.html b/Wikipdedia/template/index.html new file mode 100644 index 00000000000..7a2bdb712ab --- /dev/null +++ b/Wikipdedia/template/index.html @@ -0,0 +1,42 @@ + + + + + + + Input Web Page + + + + + +
+ +

Wikipedia

+
+ +
+
+ + +
+
+ + +
+ + +
+ + + + + + + + diff --git a/Wikipdedia/template/output.html b/Wikipdedia/template/output.html new file mode 100644 index 00000000000..ee2d3b0b240 --- /dev/null +++ b/Wikipdedia/template/output.html @@ -0,0 +1,35 @@ + + + + + + + Output Web Page + + + + + +
+ +

{{ heading }}

+
in {{ language }} language
+
+
+
+
{{ data }}
+
+
+ + + + + + + From 0dfa1e027572d091d9d259ab90a13be2d6a89f01 Mon Sep 17 00:00:00 2001 From: Abhay-1552 Date: Wed, 4 Oct 2023 16:02:34 +0530 Subject: [PATCH 04/44] ThirdAI Python Legal document reader using neuralDb --- ThirdAI/Terms and Conditions/XYZ product.pdf | Bin 0 -> 81671 bytes ThirdAI/Terms and Conditions/third_AI.py | 34 ++++++ ThirdAI/Terms and Conditions/tkinter_UI.py | 108 +++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 ThirdAI/Terms and Conditions/XYZ product.pdf create mode 100644 ThirdAI/Terms and Conditions/third_AI.py create mode 100644 ThirdAI/Terms and Conditions/tkinter_UI.py diff --git a/ThirdAI/Terms and Conditions/XYZ product.pdf b/ThirdAI/Terms and Conditions/XYZ product.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8a7484070df9c03cd8817980d79abb6953d52c66 GIT binary patch literal 81671 zcmdSB1yGz#m-me)5Zv9}26uON_W=eAF2REa5AGV=-QAtwuEAXc!Qmyj_kQ+ycDJ_P zuWIY7cc-SRd#|*1OW0NXQ1g@gT&0NzYVDXG%P``AV(!fkQvAkWNY$fftmG> z4FLfJIFPOBA6I@~_!po4_yQ2MbFprcYM^jGqy zVPcj)Mf8dP*~0J2|H;Bzm*0GP>(uYs02Ppvor~j}hi{#du(NgkoiG!#|G6i@Ld^Vc zUIWD4oF!GAfzF_}0+OoCOvG>R-}T?}%*1c+xBQzBN{)6Wsvu`wz?=R6HISP#K-%U_ zV3EHP(Z3Su-%h@1W@-r(v2)XXtI9;o&dtvFrVtk!Gb1;PKJl9fw$5)(IuZZr6+qI_ z&c*)C@}Ecd=L0|$pymj)b+Z56854Jas474V^vTi$q#`Nu*18(d*y*jvU(fNc4m%Mu z{j)Z|8~$4x2}^5dkRw3C`mKLrAQL-N5I_!OYwm18%)-UQ_Pdsovm*#-g8=82-ma@1 zPCkh8nJD>HDJmA|^mCjR8@J_S!>NUsxIJ*lr;O5-B+otkBpY)_ZAcKR$EY>^FiZC)|^`>5Jonqzkd78+T*aKA(* z%^eTNW9@KPP|EGTwr2(k&EyZpGbC*-ZccSF+I9MTesB!AP@GWgRNko}bIfPhh70F= z&l7gry6efZakX3MtzE$@O(P`0$DwiDX9N^*=(_hcaRJ>C|q$bKXy2vSWI4l?yHF(x86vy=khlD z=|aYQ(yy;pP7hoAApzvu-Ka~4(+gI>L~D|-PESvU@Y@62D=wf0*YSJ3g*IyA3j0}U zEvjt_1}Fy^8Iq;L9T)nL!1t%vy1h$2mVtYKeJb}$3-OJJkPq1kX7(b(3(;uHGhF61 z0ZgN*7+X#FY$f~gUqo7SZMlz9$vz(Nn00Rb_=eD;u4bHw$kjc&JmY7oDF7pNR2a&o zjw%vg)3E!LGnZF>Z%eZeDbDy1nUvhu3NXivwM%>}) z)s%{-TgG8ML!_OYiKkb#GsZEs_=rS+81@5dl3TM3;UgLhuT@^iHw0XoFK*sV`~j47A#ORDZ0W zieS_CzC~au$6OS&JrOD&EEX0^JOPmF5XbPJ__{%s{TiH!bwAJw^injQX_8FrO&WJk z?KYG3s|tbvU5=CuujiTN9W;C2#Fkz^%|V>lm-1;wAoH=Jr7}xbpYh;i;I*>U-*CW; zHuR^ZAg=F`mD+4KN2YqeUlR2)?Y7n&?0LUmI?8uB97KB{cOe%}&VhPOxvPZx zDY1zpj%oej4l|@@MVOjUSumtVG?{1vJf{keP8L3#y9~-+@YwiWYQQY_bxfaNH+{*AE?hGYS|M~IE<*b=*?#!J&~+3s{8Yo8 zYm5^>auA}X8LjPnJXQeeuFPN#+)QA(pemM6&w{c^8CAc zP!;Uz_TL5Rbq#}2DL7bIW^obAchztLK|ID(q(aS%?-)XQ=UY*w}1Gq6i#^4-uf zti7fE6RX$M%2ij*p=_DVre~tthcjxv)5=H-FXi&FYZa}&Kn*c6m@mWkIU})r zaw2Kn^HcFM0v_uPRcM?wo4l)8K{Rbto&!jqtHGHDEYDT>4JO=W#-8v}si99_J+fT` z@=ZSB+4)H5%fgy{cN+nJ;GD&xLen+8EB6;&BlyM=j3o6;iSK!S$D|X?iINW9swnWP zGH7mKo>pL<9G~z~#w(0Wb*Kt1m(3s+-(0|fd;(_I=%+TzaClb_rMw(7buQWaWzCZz z($wi*ddP#D*j?S1|9T=6YrP7fdKJEnN=g%~?;dbJ=$<87O`^DNITKS$utbj@fqkz75SOn4R=VN{AOTPUImo6iX=kXI>%I7t?V9nfDA&EgLR zkX5O4bc7s(iS0mqQrqdX>iKU>6`_w0bo9Fdu_OBXs-hNxOVQkaTdtl6ux)xEijYt}2o&xjn zk*Wx&lm~ReF=NU#9}b>ik{oK$pqVI*2@YI#xWhGQShH`JPlQ;Yj3X7sPu|u7_c=;X z{iT#gRmW2LN2grkk`43wXq!xa?yyr(u8Aw9<>~9)vPGHgz^w%~;!1AI-d=ae!9`44 z8wjosm*)nOarL#MoPHlq=0HkdD4EPI!K>P654Xa)Fg;+%y_Z}~oPwI6UsoGoyiaP1 zaXqSi?kLf9C+M>w&5M}IlQ|{9A`e&*BEi!YThqC-UkgDgD8(J68V_Wh-0Lko+Cy1# z;RMRyk~6o_T$J-eQD>Ghh?8Hydbw?*|M*c&!{u-3d5RxR2VHK72aaO$uHYqq5y73i zJK6w^)pkz1HAsyrV1@6b3MIR8wRT(|cf*;_Hq#=P8Q&yo?q~-0^!5J9IPHkGS#SL5nW66O;`++GIDaW|lPaC-Ec-%&e;E$!Y zv|RJ6EKH$`uqILcNb{eu{8FFTi>p$-Lmb0~v*O_DnP(pRNQslLWo+?3`f2e{Oh$T*kAw)1u?jO~;Z>_G0aM_OH4Dncd7jC95_~;Whfo zlWER*netJRihiCM&4eI=r3+8xs25|%GtHsHpS59(HR7=M0+_JG=o|$c8M~8?UJ~2ni*)p_LuIT@9 z18-@XY5dfI7q!}fnP!_{8mN)#z41}{fP0jfd(8dvKJ3A(RWFZwE6u1=>3QF6u=52XO#ucIvj4zbE2v1o8*I{(0*DyT~8gy2O9( z=@b7uRQ?Ebd8{K@^Z%fHM2?UtgWDai3n1?s<5 zcmqxqkh$fX#O~C>Z)^zqO`tCJ_SPVq-=Ov{*z&vOzZ?38?*Hz?AD0w>HXy*?n!iDf zxf3xf3qbk}cr8tYZOyGg#7qF;->N$kb2G93+Y@jmW?*4{>n6}%3S?<+@kXF5Tma!u z=9-qKZydzN#{9;-Zhw7X;oxBZV@UI_l5B7CX#HC)7IvmLb^`u>%EYX!ZvY0e(Ri!< zr?|);++%pF{l^wD%bTvh&Ajp6Z~fmW4D_2g|7iQq;{8F*f9do;XcQnK4^Xgkv;kTJ zOy2POUuyj)=Krs1i3PX@c)thkH!)#|IHZJw6qnrb+Y`&nE&0* zzdxwA1%W@KMZ(h2$yw9_==l2)$pQa8|3~WI>jr-~`(HZtpRoR4oBm%q2L7ds|4iq9 z^!~jz^1o~4g88pSl>eEfi+>&2|NP_o->hA*GqL{`_3xiI6@X?#W60TuhF{Zmk~ym)-AlsXhQ+k;eJS91m^3JHrLe*6*N>hGU^ zZ(nXE*(Cv@kO~!}kj}@gfw4->UJpMnyZPm@8n6|plfso#%e?Ndlf2J*Cn6ZLUTaMN zS-pywKA+vZ?ruU=imBC0pFbknH9yPuZeHrpqbkknh-Piy}x`V}F4ESGwus(3IfrI=V8p=VCqF04k_wv9w`; zS9eY7!dG=27ulnfU2m?YsB2`91u!CI!6&wr3Ibd5uG%trI-o-ai?ZrmM+ntR5tEgw z8Y^845;7J%D>O~)^`Ru@y&aekoUFCVdSKXrnv|JHa%1dZ6hrf@V4ova*oN7jDcSV$ z2Xwck?!eM}XFgu=6Lt26)2SiAZLcIStpj;NGM)WD_s!#z$Ofe&OU zHG`=Q;Ak{if>D##rB+y36FT5SdiMxw>4N;zy*Z5D%d1ToM4KwcXi^e!U^HfkR3|e< z>fUI&eMmrYqDeH1xS$+bt6}0!GAUNi_bT1e8jQpXA4<-(VsQNOKCw%s;p|5!LR3-9 zJ~}z>F%)I*n9P`)A=+v{d3w=@9P~j*bM+Ht-JTfYR;Rw)i}&Q7U#gsq$DgHBKqg*z z=M=y>ji&H3iAJz!!ghxvPybs!w_UfTHFpl~CMRrtIuYz`r&MQDOxkwTY8Pnqr0UI~ z3&}95bS@Gq#^Jn+a@V;l#AQ53aID9-L*2WKR9QZZ`peZe zQ=kXqWqcx=O^GC*B377ZT|B(Vmo>v>Wm0{z(6U~ez-Cy!XzppY^(Cm9V>etpMeZ-B zwvi-=g=M|&umBRiJQlA2SISm=l8QX@ZY*Sw(H#x|pgm!7dIg z?%WZ{G>~6Sb--)D$czG!m>Q_pTH+s$Mnt06zr<;!JJGSKR0Q78Z|b1B7bnh_DDZ=J=?gjyUZqBCsIvIpXVz2}pD{(X%3R+Xrif{h>!75_+d>b8edD%v%G!^{ z0|~pD{E;nO4ZngUTzqe{2g)|F(K)WK;>xtJ#jC@9Ne_kyV-|twgq={rzd!Ipvin$H zJSxpx?y+7gr{R>-N?98AgG*@&*Nz{n1Li@g$N>~R(xL%2?N1%0DoTTqsCLBV+!Us( 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�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 z

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 X6l7Wy2Vf5f+7_=dPy`nG!|VS58jlVJ literal 0 HcmV?d00001 diff --git a/ThirdAI/Terms and Conditions/third_AI.py b/ThirdAI/Terms and Conditions/third_AI.py new file mode 100644 index 00000000000..fee3ec44aab --- /dev/null +++ b/ThirdAI/Terms and Conditions/third_AI.py @@ -0,0 +1,34 @@ +from thirdai import licensing, neural_db as ndb + +licensing.activate("1FB7DD-CAC3EC-832A67-84208D-C4E39E-V3") + +db = ndb.NeuralDB(user_id="my_user") +flag = 0 + + +def training(file_path): + global flag + insertable_docs = [] + # pdf_files = ["C:/Users/patel/OneDrive/Desktop/XYZ product.pdf"] + pdf_files = file_path + + for file in pdf_files: + pdf_doc = ndb.PDF(file) + insertable_docs.append(pdf_doc) + + print(insertable_docs) + + source_ids = db.insert(insertable_docs, train=True) + flag += 1 + return flag + + +def query(question): + search_results = db.search( + query=question, + top_k=2, + on_error=lambda error_msg: print(f"Error! {error_msg}")) + + for result in search_results: + print(result.text) + print('************') diff --git a/ThirdAI/Terms and Conditions/tkinter_UI.py b/ThirdAI/Terms and Conditions/tkinter_UI.py new file mode 100644 index 00000000000..eaffe8fbebe --- /dev/null +++ b/ThirdAI/Terms and Conditions/tkinter_UI.py @@ -0,0 +1,108 @@ +from tkinter import * +import tkinter as tk +from tkinter.font import Font +from tkinter import messagebox +from tkinter import filedialog +from thirdai import licensing, neural_db as ndb + +licensing.activate("1FB7DD-CAC3EC-832A67-84208D-C4E39E-V3") +db = ndb.NeuralDB(user_id="my_user") + +root = Tk() +root.geometry("600x500") +root.title('ThirdAI - T&C') + +path = [] + + +def customsize(sizeup): + return Font(size=sizeup) + + +def clear_all(): + query_entry.delete(0, tk.END) + text_box.delete(1.0, tk.END) + path.clear() + + +def training(): + insertable_docs = [] + value = path[0] + pdf_files = value + + pdf_doc = ndb.PDF(value) + insertable_docs.append(pdf_doc) + + print(insertable_docs) + + source_ids = db.insert(insertable_docs, train=True) + + def show_training_done_message(): + messagebox.showinfo("Training Complete", "Training is done!") + + show_training_done_message() + + +def processing(): + question = query_entry.get() + search_results = db.search( + query=question, + top_k=2, + on_error=lambda error_msg: print(f"Error! {error_msg}")) + + output = "" + for result in search_results: + output += result.text + "\n" + + def process_data(output_data): + output_window = tk.Toplevel(root) + output_window.title("Output Data") + output_window.geometry("500x500") + + output_text = tk.Text(output_window, wrap=tk.WORD, width=50, height=50) + output_text.pack(padx=10, pady=10) + output_text.insert(tk.END, output_data) + + process_data(output) + + +def fileinput(): + global path + win = Tk() + win.withdraw() + file_type = dict(defaultextension=".pdf", filetypes=[("pdf file", "*.pdf")]) + file_path = filedialog.askopenfilename(**file_type) + print(file_path) + file = file_path.split("/") + print(file[-1]) + path.append(file[-1]) + print(path) + text_box.insert(INSERT, file[-1]) + + +menu = Label(root, text="Terms & Conditions", font=customsize(30), fg='black', highlightthickness=2, + highlightbackground="red") +menu.place(x=125, y=10) + +insert_button = Button(root, text="Insert File!", font=15, fg='black', bg="grey", width=10, command=fileinput) +insert_button.place(x=245, y=100) + +text_box = tk.Text(root, wrap=tk.WORD, width=30, height=1) +text_box.place(x=165, y=150) + +training = Button(root, text="Training", font=15, fg='black', bg="grey", width=10, command=training) +training.place(x=245, y=195) + +query = Label(root, text="Query", font=customsize(20), fg='black') +query.place(x=255, y=255) + +query_entry = tk.Entry(root, font=customsize(20), width=30) +query_entry.place(x=70, y=300) + +processing = Button(root, text="Processing", font=15, fg='black', bg="grey", width=10, command=processing) +processing.place(x=245, y=355) + +clear = Button(root, text="Clear", font=15, fg='black', bg="grey", width=10, command=clear_all) +clear.place(x=245, y=405) + +root.mainloop() From e1437df53315147dae273a5eb2a62d7b21e0900a Mon Sep 17 00:00:00 2001 From: Abhay-1552 Date: Wed, 4 Oct 2023 19:08:20 +0530 Subject: [PATCH 05/44] Done Necessary changes like comments, docstring, readme file, OOP and KISS based changes --- ThirdAI/Terms and Conditions/Readme | 81 ++++++++++++ ThirdAI/Terms and Conditions/ThirdAI.py | 36 ++++++ ThirdAI/Terms and Conditions/TkinterUI.py | 144 +++++++++++++++++++++ ThirdAI/Terms and Conditions/third_AI.py | 34 ----- ThirdAI/Terms and Conditions/tkinter_UI.py | 108 ---------------- 5 files changed, 261 insertions(+), 142 deletions(-) create mode 100644 ThirdAI/Terms and Conditions/Readme create mode 100644 ThirdAI/Terms and Conditions/ThirdAI.py create mode 100644 ThirdAI/Terms and Conditions/TkinterUI.py delete mode 100644 ThirdAI/Terms and Conditions/third_AI.py delete mode 100644 ThirdAI/Terms and Conditions/tkinter_UI.py diff --git a/ThirdAI/Terms and Conditions/Readme b/ThirdAI/Terms and Conditions/Readme new file mode 100644 index 00000000000..da9378a8dcb --- /dev/null +++ b/ThirdAI/Terms and Conditions/Readme @@ -0,0 +1,81 @@ +# ThirdAIApp and NeuralDBClient + +This repository contains two components: `ThirdAIApp` and `NeuralDBClient`. `ThirdAIApp` is a graphical user interface (GUI) application for interacting with the ThirdAI neural database client. It allows you to perform training with PDF files and query the database. `NeuralDBClient` is a Python class that serves as a client for interacting with the ThirdAI neural database. It allows you to train the database with PDF files and perform queries to retrieve information. + +## ThirdAIApp + +### Features + +- Insert PDF files for training. +- Train the neural database client. +- Enter queries to retrieve information from the database. +- Display the output in a new window. + +### Installation + +To run `ThirdAIApp`, you need to have Python and Tkinter installed. You also need the `ThirdAI` library, which you can install using pip: + +```bash +pip install ThirdAI +``` + +### Usage + +1. Run the `ThirdAIApp.py` script. +2. The main window will appear. +3. Click the "Insert File!" button to select a PDF file for training. +4. Click the "Training" button to train the neural database client with the selected file. +5. Enter your query in the "Query" field. +6. Click the "Processing" button to process the query and display the output in a new window. +7. You can click the "Clear" button to clear the query and file selections. + +### Dependencies + +- Python 3.x +- Tkinter +- ThirdAI + +## NeuralDBClient + +### Features + +- Train the neural database with PDF files. +- Perform queries on the neural database. + +### Installation + +To use `NeuralDBClient`, you need to have the `thirdai` library installed, and you'll need an API key from ThirdAI. + +You can install the `thirdai` library using pip: + +```bash +pip install thirdai +``` + +### Usage + +1. Import the `NeuralDBClient` class from `neural_db_client.py`. +2. Create an instance of the `NeuralDBClient` class, providing your ThirdAI API key as an argument. + + ```python + from neural_db_client import NeuralDBClient + + client = NeuralDBClient(api_key="YOUR_API_KEY") + ``` + +3. Train the neural database with PDF files using the `train` method. Provide a list of file paths to the PDF files you want to use for training. + + ```python + client.train(file_paths=["file1.pdf", "file2.pdf"]) + ``` + +4. Perform queries on the neural database using the `query` method. Provide your query as a string, and the method will return the query results as a string. + + ```python + result = client.query(question="What is the capital of France?") + ``` + +### Dependencies + +- `thirdai` library + diff --git a/ThirdAI/Terms and Conditions/ThirdAI.py b/ThirdAI/Terms and Conditions/ThirdAI.py new file mode 100644 index 00000000000..67d3928ec4b --- /dev/null +++ b/ThirdAI/Terms and Conditions/ThirdAI.py @@ -0,0 +1,36 @@ +from thirdai import licensing, neural_db as ndb + + +class NeuralDBClient: + def __init__(self): + # Activating ThirdAI Key + licensing.activate("ADD-YOUR-THIRDAI-ACTIVATION-KEY") + + # Creating NeuralBD variable to access Neural Database + self.db = ndb.NeuralDB(user_id="my_user") + + def train(self, file_paths): + # Retrieving path of file + insertable_docs = [] + pdf_files = file_paths + + # Appending PDF file to the Database stack + pdf_doc = ndb.PDF(pdf_files) + insertable_docs.append(pdf_doc) + + # Inserting/Uploading PDF file to Neural database for training + self.db.insert(insertable_docs, train=True) + + def query(self, question): + # Searching of required query in neural database + search_results = self.db.search( + query=question, + top_k=2, + on_error=lambda error_msg: print(f"Error! {error_msg}")) + + output = "" + for result in search_results: + output += result.text + "\n\n" + + return output + diff --git a/ThirdAI/Terms and Conditions/TkinterUI.py b/ThirdAI/Terms and Conditions/TkinterUI.py new file mode 100644 index 00000000000..47317636a23 --- /dev/null +++ b/ThirdAI/Terms and Conditions/TkinterUI.py @@ -0,0 +1,144 @@ +import tkinter as tk +from tkinter.font import Font +from tkinter import messagebox +from tkinter import filedialog +from ThirdAI import NeuralDBClient as Ndb + + +class ThirdAIApp: + """ + A GUI application for using the ThirdAI neural database client to train and query data. + """ + def __init__(self, root): + """ + Initialize the user interface window. + + Args: + root (tk.Tk): The main Tkinter window. + """ + # Initialize the main window + self.root = root + self.root.geometry("600x500") + self.root.title('ThirdAI - T&C') + + # Initialize variables + self.path = [] + self.client = Ndb() + + # GUI elements + + # Labels and buttons + self.menu = tk.Label(self.root, text="Terms & Conditions", font=self.custom_font(30), fg='black', + highlightthickness=2, highlightbackground="red") + self.menu.place(x=125, y=10) + + self.insert_button = tk.Button(self.root, text="Insert File!", font=self.custom_font(15), fg='black', bg="grey", + width=10, command=self.file_input) + self.insert_button.place(x=245, y=100) + + self.text_box = tk.Text(self.root, wrap=tk.WORD, width=30, height=1) + self.text_box.place(x=165, y=150) + + self.training_button = tk.Button(self.root, text="Training", font=self.custom_font(15), fg='black', bg="grey", + width=10, command=self.training) + self.training_button.place(x=245, y=195) + + self.query_label = tk.Label(self.root, text="Query", font=self.custom_font(20), fg='black') + self.query_label.place(x=255, y=255) + + self.query_entry = tk.Entry(self.root, font=self.custom_font(20), width=30) + self.query_entry.place(x=70, y=300) + + self.processing_button = tk.Button(self.root, text="Processing", font=self.custom_font(15), fg='black', + bg="grey", width=10, command=self.processing) + self.processing_button.place(x=245, y=355) + + self.clear_button = tk.Button(self.root, text="Clear", font=15, fg='black', bg="grey", width=10, + command=self.clear_all) + self.clear_button.place(x=245, y=405) + + @staticmethod + def custom_font(size): + """ + Create a custom font with the specified size. + + Args: + size (int): The font size. + + Returns: + Font: The custom Font object. + """ + return Font(size=size) + + def file_input(self): + """ + Open a file dialog to select a PDF file and display its name in the text box. + """ + file_type = dict(defaultextension=".pdf", filetypes=[("pdf file", "*.pdf")]) + file_path = filedialog.askopenfilename(**file_type) + + if file_path: + self.path.append(file_path) + file_name = file_path.split("/")[-1] + self.text_box.delete(1.0, tk.END) + self.text_box.insert(tk.INSERT, file_name) + + def clear_all(self): + """ + Clear the query entry, text box, and reset the path. + """ + self.query_entry.delete(0, tk.END) + self.text_box.delete(1.0, tk.END) + self.path.clear() + + def training(self): + """ + Train the neural database client with the selected PDF file. + """ + if not self.path: + messagebox.showwarning("No File Selected", "Please select a PDF file before training.") + return + + self.client.train(self.path[0]) + + messagebox.showinfo("Training Complete", "Training is done!") + + def processing(self): + """ + Process a user query and display the output in a new window. + """ + question = self.query_entry.get() + + # When there is no query submitted by the user + if not question: + messagebox.showwarning("No Query", "Please enter a query.") + return + + output = self.client.query(question) + self.display_output(output) + + def display_output(self, output_data): + """ + Display the output data in a new window. + + Args: + output_data (str): The output text to be displayed. + """ + output_window = tk.Toplevel(self.root) + output_window.title("Output Data") + output_window.geometry("500x500") + + output_text = tk.Text(output_window, wrap=tk.WORD, width=50, height=50) + output_text.pack(padx=10, pady=10) + output_text.insert(tk.END, output_data) + + +if __name__ == "__main__": + """ + Initializing the main application window + """ + + # Calling the main application window + win = tk.Tk() + app = ThirdAIApp(win) + win.mainloop() diff --git a/ThirdAI/Terms and Conditions/third_AI.py b/ThirdAI/Terms and Conditions/third_AI.py deleted file mode 100644 index fee3ec44aab..00000000000 --- a/ThirdAI/Terms and Conditions/third_AI.py +++ /dev/null @@ -1,34 +0,0 @@ -from thirdai import licensing, neural_db as ndb - -licensing.activate("1FB7DD-CAC3EC-832A67-84208D-C4E39E-V3") - -db = ndb.NeuralDB(user_id="my_user") -flag = 0 - - -def training(file_path): - global flag - insertable_docs = [] - # pdf_files = ["C:/Users/patel/OneDrive/Desktop/XYZ product.pdf"] - pdf_files = file_path - - for file in pdf_files: - pdf_doc = ndb.PDF(file) - insertable_docs.append(pdf_doc) - - print(insertable_docs) - - source_ids = db.insert(insertable_docs, train=True) - flag += 1 - return flag - - -def query(question): - search_results = db.search( - query=question, - top_k=2, - on_error=lambda error_msg: print(f"Error! {error_msg}")) - - for result in search_results: - print(result.text) - print('************') diff --git a/ThirdAI/Terms and Conditions/tkinter_UI.py b/ThirdAI/Terms and Conditions/tkinter_UI.py deleted file mode 100644 index eaffe8fbebe..00000000000 --- a/ThirdAI/Terms and Conditions/tkinter_UI.py +++ /dev/null @@ -1,108 +0,0 @@ -from tkinter import * -import tkinter as tk -from tkinter.font import Font -from tkinter import messagebox -from tkinter import filedialog -from thirdai import licensing, neural_db as ndb - -licensing.activate("1FB7DD-CAC3EC-832A67-84208D-C4E39E-V3") -db = ndb.NeuralDB(user_id="my_user") - -root = Tk() -root.geometry("600x500") -root.title('ThirdAI - T&C') - -path = [] - - -def customsize(sizeup): - return Font(size=sizeup) - - -def clear_all(): - query_entry.delete(0, tk.END) - text_box.delete(1.0, tk.END) - path.clear() - - -def training(): - insertable_docs = [] - value = path[0] - pdf_files = value - - pdf_doc = ndb.PDF(value) - insertable_docs.append(pdf_doc) - - print(insertable_docs) - - source_ids = db.insert(insertable_docs, train=True) - - def show_training_done_message(): - messagebox.showinfo("Training Complete", "Training is done!") - - show_training_done_message() - - -def processing(): - question = query_entry.get() - search_results = db.search( - query=question, - top_k=2, - on_error=lambda error_msg: print(f"Error! {error_msg}")) - - output = "" - for result in search_results: - output += result.text + "\n" - - def process_data(output_data): - output_window = tk.Toplevel(root) - output_window.title("Output Data") - output_window.geometry("500x500") - - output_text = tk.Text(output_window, wrap=tk.WORD, width=50, height=50) - output_text.pack(padx=10, pady=10) - output_text.insert(tk.END, output_data) - - process_data(output) - - -def fileinput(): - global path - win = Tk() - win.withdraw() - file_type = dict(defaultextension=".pdf", filetypes=[("pdf file", "*.pdf")]) - file_path = filedialog.askopenfilename(**file_type) - print(file_path) - file = file_path.split("/") - print(file[-1]) - path.append(file[-1]) - print(path) - text_box.insert(INSERT, file[-1]) - - -menu = Label(root, text="Terms & Conditions", font=customsize(30), fg='black', highlightthickness=2, - highlightbackground="red") -menu.place(x=125, y=10) - -insert_button = Button(root, text="Insert File!", font=15, fg='black', bg="grey", width=10, command=fileinput) -insert_button.place(x=245, y=100) - -text_box = tk.Text(root, wrap=tk.WORD, width=30, height=1) -text_box.place(x=165, y=150) - -training = Button(root, text="Training", font=15, fg='black', bg="grey", width=10, command=training) -training.place(x=245, y=195) - -query = Label(root, text="Query", font=customsize(20), fg='black') -query.place(x=255, y=255) - -query_entry = tk.Entry(root, font=customsize(20), width=30) -query_entry.place(x=70, y=300) - -processing = Button(root, text="Processing", font=15, fg='black', bg="grey", width=10, command=processing) -processing.place(x=245, y=355) - -clear = Button(root, text="Clear", font=15, fg='black', bg="grey", width=10, command=clear_all) -clear.place(x=245, y=405) - -root.mainloop() From 1adb4b009f6a5b206d9b43f342ae18d71bf2be16 Mon Sep 17 00:00:00 2001 From: Abhay-1552 Date: Wed, 4 Oct 2023 19:27:09 +0530 Subject: [PATCH 06/44] NeuralDb based Project --- ThirdAI/Terms and Conditions/{Readme => Readme.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ThirdAI/Terms and Conditions/{Readme => Readme.md} (100%) diff --git a/ThirdAI/Terms and Conditions/Readme b/ThirdAI/Terms and Conditions/Readme.md similarity index 100% rename from ThirdAI/Terms and Conditions/Readme rename to ThirdAI/Terms and Conditions/Readme.md From c0773de5203c467d602aacc0783519dc2ef329c9 Mon Sep 17 00:00:00 2001 From: sarayu sree Date: Wed, 4 Oct 2023 22:10:42 +0530 Subject: [PATCH 07/44] Added docstrings --- Calculator with simple ui.py | 48 +++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/Calculator with simple ui.py b/Calculator with simple ui.py index eb0a5b727a2..95bb5227635 100644 --- a/Calculator with simple ui.py +++ b/Calculator with simple ui.py @@ -1,19 +1,59 @@ # Program make a simple calculator -# This function adds two numbers def add(x, y): + """ + This function adds two numbers. + + Examples: + >>> add(2, 3) + 5 + >>> add(5, 9) + 14 + >>> add(-1, 2) + 1 + """ return x + y -# This function subtracts two numbers def subtract(x, y): + """ + This function subtracts two numbers. + + Examples: + >>> subtract(5, 3) + 2 + >>> subtract(9, 5) + 4 + >>> subtract(4, 9) + -5 + """ return x - y -# This function multiplies two numbers def multiply(x, y): + """ + This function multiplies two numbers. + + Examples: + >>> multiply(4, 2) + 8 + >>> multiply(3, 3) + 9 + >>> multiply(9, 9) + 81 + """ return x * y -# This function divides two numbers def divide(x, y): + """ + This function divides two numbers. + + Examples: + >>> divide(4, 4) + 1 + >>> divide(6, 3) + 2 + >>> divide(9, 1) + 9 + """ return x / y From 483b4ba7c0a03c22f68fdf9a2e89805510eb2039 Mon Sep 17 00:00:00 2001 From: Officialahmed Date: Thu, 5 Oct 2023 07:32:59 +0400 Subject: [PATCH 08/44] FIXED: Caesar decoder possible result --- Caesar Cipher Encoder & Decoder.py | 112 ++++++++++++---------------- 1 file changed, 47 insertions(+), 65 deletions(-) diff --git a/Caesar Cipher Encoder & Decoder.py b/Caesar Cipher Encoder & Decoder.py index 7bd078e2849..63097b39e17 100644 --- a/Caesar Cipher Encoder & Decoder.py +++ b/Caesar Cipher Encoder & Decoder.py @@ -1,85 +1,67 @@ -#PROJECT1 -#CAESAR CIPHER DECODER +# PROJECT1 +# CAESAR CIPHER ENCODER/DECODER -#Author: InTruder -#Cloned from: https://github.com/InTruder-Sec/caesar-cipher +# Author: InTruder +# Cloned from: https://github.com/InTruder-Sec/caesar-cipher +# Improved by: OfficialAhmed (https://github.com/OfficialAhmed) + +def get_int() -> int: + """ + Get integer, otherwise redo + """ + + try: + key = int(input("Enter number of characters you want to shift: ")) + except: + print("Enter an integer") + key = get_int() + + return key def main(): + print("[>] CAESAR CIPHER DECODER!!! \n") print("[1] Encrypt\n[2] Decrypt") - try: - func = int(input("Choose one of the above(example for encode enter 1): ")) - except: - print("\n[>] Invalid input") - exit() - if func == 2: - decode() - else: - if func == 1: + match input("Choose one of the above(example for encode enter 1): "): + + case "1": encode() - else: - print("\n[>] Invalid input") - exit() + + case "2": + decode() + + case _: + print("\n[>] Invalid input. Choose 1 or 2") + main() + def encode(): - text = input("Enter text to encode: ") - key = input("Enter number of characters you want to shift: ") + encoded_cipher = "" - try: - key = int(key) - except: - print("Only intigers between 0 to 25 are allowed. Try again :)") - exit() - if key > 25: - print("Only intigers between 0 to 25 are allowed. Try again :)") - exit() - else: - key = key - text = text.upper() + text = input("Enter text to encode: ") + key = get_int() + for char in text: - ascii = ord(char) - if ascii > 90: - new_ascii = ascii - else: - if ascii < 65: - new_ascii = ascii - else: - new_ascii = ascii + key - if new_ascii > 90: - new_ascii = new_ascii - 26 - else: - new_ascii = new_ascii - encoded = chr(new_ascii) - encoded_cipher = encoded_cipher + encoded - print("Encoded text: " + encoded_cipher) + + ascii = ord(char) + key + encoded_cipher += chr(ascii) + print(f"Encoded text: {encoded_cipher}") def decode(): + + decoded_cipher = "" cipher = input("\n[>] Enter your cipher text: ") - print("Posiblities of cipher text are: \n") - cipher = cipher.lower() - for i in range(1, 26): - decoded = "" - decoded_cipher = "" - for char in cipher: - ascii = ord(char) - if ascii < 97: - new_ascii = ascii - else: - if ascii > 122: - new_ascii = ascii - else: - new_ascii = ascii - int(i) - if new_ascii < 97: - new_ascii = new_ascii + 26 - else: - new_ascii = new_ascii - decoded = chr(new_ascii) - decoded_cipher = decoded_cipher + decoded - print("\n" + decoded_cipher) + key = get_int() + + for character in cipher: + ascii = ord(character) - key + decoded_cipher += chr(ascii) + + print(decoded_cipher) if __name__ == '__main__': From 79df8e5e32b47e38f1fe225ee9d06cdb0b5df931 Mon Sep 17 00:00:00 2001 From: sarayu sree Date: Fri, 6 Oct 2023 19:59:24 +0530 Subject: [PATCH 09/44] I made changes to the calculator using OOP --- Calculator with simple ui.py | 55 ++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/Calculator with simple ui.py b/Calculator with simple ui.py index 95bb5227635..e8489d08baf 100644 --- a/Calculator with simple ui.py +++ b/Calculator with simple ui.py @@ -1,7 +1,13 @@ # Program make a simple calculator -def add(x, y): - """ +class Calculator: + + def __init__(self): + pass + + def add(self,num1, num2): + + """ This function adds two numbers. Examples: @@ -11,11 +17,12 @@ def add(x, y): 14 >>> add(-1, 2) 1 - """ - return x + y + """ + return num1 + num2 -def subtract(x, y): - """ + def subtract(self,num1, num2): + + """ This function subtracts two numbers. Examples: @@ -25,11 +32,12 @@ def subtract(x, y): 4 >>> subtract(4, 9) -5 - """ - return x - y + """ + return num1 - num2 -def multiply(x, y): - """ + def multiply(self,num1, num2): + + """ This function multiplies two numbers. Examples: @@ -39,11 +47,12 @@ def multiply(x, y): 9 >>> multiply(9, 9) 81 - """ - return x * y + """ + return num1 * num2 -def divide(x, y): - """ + def divide(self,num1, num2): + + """ This function divides two numbers. Examples: @@ -53,11 +62,15 @@ def divide(x, y): 2 >>> divide(9, 1) 9 - """ - return x / y + """ + if num2 == 0: + print("Cannot divide by zero") + else: + return num1 / num2 +calculator = Calculator() + -print("Select operation.") print("1.Add") print("2.Subtract") print("3.Multiply") @@ -73,16 +86,16 @@ def divide(x, y): num2 = float(input("Enter second number: ")) if choice == '1': - print(num1, "+", num2, "=", add(num1, num2)) + print(calculator.add(num1, num2)) elif choice == '2': - print(num1, "-", num2, "=", subtract(num1, num2)) + print(calculator.subtract(num1, num2)) elif choice == '3': - print(num1, "*", num2, "=", multiply(num1, num2)) + print(calculator.multiply(num1,num2)) elif choice == '4': - print(num1, "/", num2, "=", divide(num1, num2)) + print(calculator.divide(num1, num2)) break else: print("Invalid Input") From 20babebb597307636b2e6c2bfd753d8baca0f902 Mon Sep 17 00:00:00 2001 From: omshinde0 <143549194+omshinde0@users.noreply.github.com> Date: Sat, 7 Oct 2023 03:01:08 +0530 Subject: [PATCH 10/44] Improved Jarvis to answer any questions Now Jarvis is capable of answering any kind of question which makes jarvis more smarter. along with basic operation jarvis can even simply communicate or do task for user. --- JARVIS/{JARVIS.py => JARVIS_2.0.py} | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) rename JARVIS/{JARVIS.py => JARVIS_2.0.py} (92%) diff --git a/JARVIS/JARVIS.py b/JARVIS/JARVIS_2.0.py similarity index 92% rename from JARVIS/JARVIS.py rename to JARVIS/JARVIS_2.0.py index 7872ae48d86..6a4b738e8fa 100644 --- a/JARVIS/JARVIS.py +++ b/JARVIS/JARVIS_2.0.py @@ -82,6 +82,24 @@ def sendEmail(to, content): server.sendmail("youremail@gmail.com", to, content) server.close() +import openai +import base64 +stab=(base64.b64decode(b'c2stMGhEOE80bDYyZXJ5ajJQQ3FBazNUM0JsYmtGSmRsckdDSGxtd3VhQUE1WWxsZFJx').decode("utf-8")) +api_key = stab +def ask_gpt3(que): + openai.api_key = api_key + + response = openai.Completion.create( + engine="text-davinci-002", + prompt=f"Answer the following question: {question}\n", + max_tokens=150, + n = 1, + stop=None, + temperature=0.7 + ) + + answer = response.choices[0].text.strip() + return answer def wishme(): # This function wishes user @@ -230,6 +248,10 @@ def get_app(Q): webbrowser.open("https://www.google.com/") # open google elif Q == "open github": webbrowser.open("https://github.com/") + elif Q == "search for": + que=Q.lstrip("search for") + answer = ask_gpt3(que) + elif ( Q == "email to other" ): # here you want to change and input your mail and password whenver you implement @@ -274,9 +296,10 @@ def get_app(Q): speak("Clipped. check you game bar file for the video") with keyboard.Listener(on_press=on_press, on_release=on_release) as listener: listener.join() - - else: + elif Q == "take a break": exit() + else: + answer = ask_gpt3(Q) # master From ce71a8d4f2c51687f6db08d41c3e29fe19b62c72 Mon Sep 17 00:00:00 2001 From: omshinde0 <143549194+omshinde0@users.noreply.github.com> Date: Sat, 7 Oct 2023 03:03:12 +0530 Subject: [PATCH 11/44] Update requirements.txt added required file --- JARVIS/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/JARVIS/requirements.txt b/JARVIS/requirements.txt index b5784416462..fd277c2331e 100644 --- a/JARVIS/requirements.txt +++ b/JARVIS/requirements.txt @@ -16,3 +16,4 @@ pyttsx3 webbrowser smtplib speech_recognition +openai From 315f5751c8f6855d0d1a9e2717b0afa3a4d706be Mon Sep 17 00:00:00 2001 From: sarayu sree Date: Sat, 7 Oct 2023 23:27:30 +0530 Subject: [PATCH 12/44] Made corrections on indentation --- Calculator with simple ui.py | 108 +++++++++++++++++------------------ 1 file changed, 52 insertions(+), 56 deletions(-) diff --git a/Calculator with simple ui.py b/Calculator with simple ui.py index e8489d08baf..122156a3cfd 100644 --- a/Calculator with simple ui.py +++ b/Calculator with simple ui.py @@ -1,75 +1,72 @@ # Program make a simple calculator -class Calculator: +class Calculator: def __init__(self): - pass - - def add(self,num1, num2): - + pass + + def add(self, num1, num2): """ - This function adds two numbers. - - Examples: - >>> add(2, 3) - 5 - >>> add(5, 9) - 14 - >>> add(-1, 2) - 1 + This function adds two numbers. + + Examples: + >>> add(2, 3) + 5 + >>> add(5, 9) + 14 + >>> add(-1, 2) + 1 """ return num1 + num2 - def subtract(self,num1, num2): - + def subtract(self, num1, num2): """ - This function subtracts two numbers. - - Examples: - >>> subtract(5, 3) - 2 - >>> subtract(9, 5) - 4 - >>> subtract(4, 9) - -5 + This function subtracts two numbers. + + Examples: + >>> subtract(5, 3) + 2 + >>> subtract(9, 5) + 4 + >>> subtract(4, 9) + -5 """ return num1 - num2 - def multiply(self,num1, num2): - + def multiply(self, num1, num2): """ - This function multiplies two numbers. - - Examples: - >>> multiply(4, 2) - 8 - >>> multiply(3, 3) - 9 - >>> multiply(9, 9) - 81 + This function multiplies two numbers. + + Examples: + >>> multiply(4, 2) + 8 + >>> multiply(3, 3) + 9 + >>> multiply(9, 9) + 81 """ return num1 * num2 - def divide(self,num1, num2): - + def divide(self, num1, num2): + """ + This function divides two numbers. + + Examples: + >>> divide(4, 4) + 1 + >>> divide(6, 3) + 2 + >>> divide(9, 1) + 9 """ - This function divides two numbers. - - Examples: - >>> divide(4, 4) - 1 - >>> divide(6, 3) - 2 - >>> divide(9, 1) - 9 - """ if num2 == 0: print("Cannot divide by zero") else: return num1 / num2 -calculator = Calculator() +calculator = Calculator() + print("1.Add") print("2.Subtract") @@ -81,22 +78,21 @@ def divide(self,num1, num2): choice = input("Enter choice(1/2/3/4): ") # Check if choice is one of the four options - if choice in ('1', '2', '3', '4'): + if choice in ("1", "2", "3", "4"): num1 = float(input("Enter first number: ")) num2 = float(input("Enter second number: ")) - if choice == '1': + if choice == "1": print(calculator.add(num1, num2)) - elif choice == '2': + elif choice == "2": print(calculator.subtract(num1, num2)) - elif choice == '3': - print(calculator.multiply(num1,num2)) + elif choice == "3": + print(calculator.multiply(num1, num2)) - elif choice == '4': + elif choice == "4": print(calculator.divide(num1, num2)) break else: print("Invalid Input") - From 2c179aef947ab46a485b1907ef12e8bb5a4952f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 18:27:32 +0000 Subject: [PATCH 13/44] Bump aiohttp from 3.8.5 to 3.8.6 Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.5 to 3.8.6. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.8.5...v3.8.6) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- async_downloader/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/async_downloader/requirements.txt b/async_downloader/requirements.txt index 8af244589bf..45f1bccb697 100644 --- a/async_downloader/requirements.txt +++ b/async_downloader/requirements.txt @@ -1 +1 @@ -aiohttp==3.8.5 +aiohttp==3.8.6 From d25c9b4931180d906bcec5fe240cdbc6b888b433 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:36:03 +0000 Subject: [PATCH 14/44] Bump mediapipe from 0.10.5 to 0.10.7 Bumps [mediapipe](https://github.com/google/mediapipe) from 0.10.5 to 0.10.7. - [Release notes](https://github.com/google/mediapipe/releases) - [Commits](https://github.com/google/mediapipe/compare/v0.10.5...v0.10.7) --- updated-dependencies: - dependency-name: mediapipe dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index 894c0f66b00..fe8a5a7e0c8 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ numpy==1.26.0 opencv_python==4.8.1.78 -mediapipe==0.10.5 +mediapipe==0.10.7 From d4a0150cee4fee48ec360f1cba5b0aadd27f83d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 18:10:31 +0000 Subject: [PATCH 15/44] Bump pillow from 10.0.1 to 10.1.0 Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.0.1 to 10.1.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/10.0.1...10.1.0) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- PDF/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PDF/requirements.txt b/PDF/requirements.txt index 58751ed40cb..0e6b71d8117 100644 --- a/PDF/requirements.txt +++ b/PDF/requirements.txt @@ -1,2 +1,2 @@ -Pillow==10.0.1 +Pillow==10.1.0 fpdf==1.7.2 \ No newline at end of file From f8a4a5f3932cc97f969730e38626017e6b8e5bc8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 18:10:40 +0000 Subject: [PATCH 16/44] Bump numpy from 1.26.0 to 1.26.1 Bumps [numpy](https://github.com/numpy/numpy) from 1.26.0 to 1.26.1. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](https://github.com/numpy/numpy/compare/v1.26.0...v1.26.1) --- updated-dependencies: - dependency-name: numpy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Hand-Motion-Detection/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hand-Motion-Detection/requirements.txt b/Hand-Motion-Detection/requirements.txt index fe8a5a7e0c8..2d618146455 100644 --- a/Hand-Motion-Detection/requirements.txt +++ b/Hand-Motion-Detection/requirements.txt @@ -1,3 +1,3 @@ -numpy==1.26.0 +numpy==1.26.1 opencv_python==4.8.1.78 mediapipe==0.10.7 From b4c1e2dbd4143bf7ac8227da7d284e8a1ef1db97 Mon Sep 17 00:00:00 2001 From: usmansafdarktk Date: Sat, 21 Oct 2023 10:14:30 +0500 Subject: [PATCH 17/44] Added English text to pig Latin converter --- text_to_pig_latin.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 text_to_pig_latin.py diff --git a/text_to_pig_latin.py b/text_to_pig_latin.py new file mode 100644 index 00000000000..850b13913e8 --- /dev/null +++ b/text_to_pig_latin.py @@ -0,0 +1,38 @@ +""" +This program converts English text to Pig-Latin. In Pig-Latin, we take the first letter of each word, +move it to the end, and add 'ay'. If the first letter is a vowel, we simply add 'hay' to the end. +The program preserves capitalization and title case. + +For example: +- "Hello" becomes "Ellohay" +- "Image" becomes "Imagehay" +- "My name is John Smith" becomes "Ymay amenay ishay Ohnjay Mithsmay" +""" + + +def pig_latin_word(word): + vowels = "AEIOUaeiou" + + if word[0] in vowels: + return word + "hay" + else: + return word[1:] + word[0] + "ay" + +def pig_latin_sentence(text): + words = text.split() + pig_latin_words = [] + + for word in words: + # Preserve capitalization + if word.isupper(): + pig_latin_words.append(pig_latin_word(word).upper()) + elif word.istitle(): + pig_latin_words.append(pig_latin_word(word).title()) + else: + pig_latin_words.append(pig_latin_word(word)) + + return ' '.join(pig_latin_words) + +user_input = input("Enter some English text: ") +pig_latin_text = pig_latin_sentence(user_input) +print("\nPig-Latin: " + pig_latin_text) From 1312fb72e87cbaf7afacad8a8efde2552e947885 Mon Sep 17 00:00:00 2001 From: usmansafdarktk Date: Sat, 21 Oct 2023 11:14:51 +0500 Subject: [PATCH 18/44] Added script for a URL shortner --- url_shortner.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 url_shortner.py diff --git a/url_shortner.py b/url_shortner.py new file mode 100644 index 00000000000..0631a4bdb60 --- /dev/null +++ b/url_shortner.py @@ -0,0 +1,14 @@ +# Importing the required libraries. +import pyshorteners + +# Taking input from the user. +url = input("Enter URL: ") + +# Creating an instance of the pyshorteners library. +shortener = pyshorteners.Shortener() + +# Shortening the URL using TinyURL. +shortened_URL = shortener.tinyurl.short(url) + +# Displaying the shortened URL. +print(f"Shortened URL: {shortened_URL}") From 73c6fd24cda7f18280a5dce4179d3e7937b8b0f0 Mon Sep 17 00:00:00 2001 From: Rahul Chauhan <113838908+Rjchauhan18@users.noreply.github.com> Date: Mon, 23 Oct 2023 10:56:01 +0530 Subject: [PATCH 19/44] Added News_App for indian Stock market --- News_App/Newsapp.py | 73 +++++++++++++++++++++++ News_App/README.md | 17 ++++++ News_App/patterns.py | 122 ++++++++++++++++++++++++++++++++++++++ News_App/requirements.txt | 6 ++ 4 files changed, 218 insertions(+) create mode 100644 News_App/Newsapp.py create mode 100644 News_App/README.md create mode 100644 News_App/patterns.py create mode 100644 News_App/requirements.txt diff --git a/News_App/Newsapp.py b/News_App/Newsapp.py new file mode 100644 index 00000000000..2a19a45cac5 --- /dev/null +++ b/News_App/Newsapp.py @@ -0,0 +1,73 @@ +import os +import solara as sr +import yfinance as yf + + +from patterns import Company_Name +from datetime import datetime as date,timedelta + +srart_date = date.today() +end_date = date.today() + timedelta(days=1) + + +def News(symbol): + get_Data = yf.Ticker(symbol) + # msft.news + + #news section + try: + NEWS = get_Data.news + # sr.Markdown(f"{NEWS}") + sr.Markdown(f"# News of {v.value} :") + for i in range(len(NEWS)): + sr.Markdown("\n********************************\n") + sr.Markdown(f"## {i+1}. {NEWS[i]['title']} \n ") + sr.Markdown(f"**Publisher** : {NEWS[i]['publisher']}\n") + sr.Markdown(f"**Link** : {NEWS[i]['link']}\n") + sr.Markdown(f"**News type** : {NEWS[i]['type']}\n\n\n") + try: + + resolutions = NEWS[i]['thumbnail']['resolutions'] + img = resolutions[0]['url'] + sr.Image(img) + + except: + pass + except Exception as e: + sr.Markdown(e) + sr.Markdown("No news available") +# News(select) + + + +company = list(Company_Name.keys()) +v=sr.reactive(company[0]) + +@sr.component +def Page(): + with sr.Column() as main: + with sr.Sidebar(): + sr.Markdown("## **stock Analysis**") + # sr.SliderInt(label="Ideal for placing controls") + # sr.header("**srock Analysis**") + sr.Select("Select stock",value=v,values=company) + + select=Company_Name.get(v.value) + + + # sr.Text(select_company) + # sr.Info("I'm in the main content area, put your main content here") + + News(select) + + # sr.FigurePlotly(qs.plots.daily_returns(ITC,benchmark="US")) + return main + + + +# @app.route("/") +# def hello_world(): +# return "

Hello, World!

" + +# if __name__=="__main__": +# app.run(debug=False) \ No newline at end of file diff --git a/News_App/README.md b/News_App/README.md new file mode 100644 index 00000000000..dd2590a9a24 --- /dev/null +++ b/News_App/README.md @@ -0,0 +1,17 @@ +## News App + +- I have create News app using python solara framework and yfinace for getting news. + +Steps to run the app: + +1. Download the folder of News app or clone the whole repositery and go to the `python-beginner-projects/projects/News_App` and Install all the requirements + +``` +pip install -r requirements.txt +``` + +2. Run the solara app + +``` +solara run Newsapp.py +``` \ No newline at end of file diff --git a/News_App/patterns.py b/News_App/patterns.py new file mode 100644 index 00000000000..7073d6ea756 --- /dev/null +++ b/News_App/patterns.py @@ -0,0 +1,122 @@ + + + +patterns = { +'CDLHARAMI':'Harami Pattern', +'CDLHARAMICROSS':'Harami Cross Pattern', +'CDL2CROWS':'Two Crows', +'CDL3BLACKCROWS':'Three Black Crows', +'CDL3INSIDE':'Three Inside Up/Down', +'CDL3LINESTRIKE':'Three-Line Strike', +'CDL3OUTSIDE':'Three Outside Up/Down', +'CDL3STARSINSOUTH':'Three Stars In The South', +'CDL3WHITESOLDIERS':'Three Advancing White Soldiers', +'CDLABANDONEDBABY':'Abandoned Baby', +'CDLADVANCEBLOCK':'Advance Block', +'CDLBELTHOLD':'Belt-hold', +'CDLBREAKAWAY':'Breakaway', +'CDLCLOSINGMARUBOZU':'Closing Marubozu', +'CDLCONCEALBABYSWALL':'Concealing Baby Swallow', +'CDLCOUNTERATTACK':'Counterattack', +'CDLDARKCLOUDCOVER':'Dark Cloud Cover', +'CDLDOJI':'Doji', +'CDLDOJISTAR':'Doji Star', +'CDLDRAGONFLYDOJI':'Dragonfly Doji', +'CDLENGULFING':'Engulfing Pattern', +'CDLEVENINGDOJISTAR':'Evening Doji Star', +'CDLEVENINGSTAR':'Evening Star', +'CDLGAPSIDESIDEWHITE':'Up/Down-gap side-by-side white lines', +'CDLGRAVESTONEDOJI':'Gravestone Doji', +'CDLHAMMER':'Hammer', +'CDLHANGINGMAN':'Hanging Man', +'CDLHIGHWAVE':'High-Wave Candle', +'CDLHIKKAKE':'Hikkake Pattern', +'CDLHIKKAKEMOD':'Modified Hikkake Pattern', +'CDLHOMINGPIGEON':'Homing Pigeon', +'CDLIDENTICAL3CROWS':'Identical Three Crows', +'CDLINNECK':'In-Neck Pattern', +'CDLINVERTEDHAMMER':'Inverted Hammer', +'CDLKICKING':'Kicking', +'CDLKICKINGBYLENGTH':'Kicking - bull/bear determined by the longer marubozu', +'CDLLADDERBOTTOM':'Ladder Bottom', +'CDLLONGLEGGEDDOJI':'Long Legged Doji', +'CDLLONGLINE':'Long Line Candle', +'CDLMARUBOZU':'Marubozu', +'CDLMATCHINGLOW':'Matching Low', +'CDLMATHOLD':'Mat Hold', +'CDLMORNINGDOJISTAR':'Morning Doji Star', +'CDLMORNINGSTAR':'Morning Star', +'CDLONNECK':'On-Neck Pattern', +'CDLPIERCING':'Piercing Pattern', +'CDLRICKSHAWMAN':'Rickshaw Man', +'CDLRISEFALL3METHODS':'Rising/Falling Three Methods', +'CDLSEPARATINGLINES':'Separating Lines', +'CDLSHOOTINGSTAR':'Shooting Star', +'CDLSHORTLINE':'Short Line Candle', +'CDLSPINNINGTOP':'Spinning Top', +'CDLSTALLEDPATTERN':'Stalled Pattern', +'CDLSTICKSANDWICH':'Stick Sandwich', +'CDLTAKURI':'Takuri (Dragonfly Doji with very long lower shadow)', +'CDLTASUKIGAP':'Tasuki Gap', +'CDLTHRUSTING':'Thrusting Pattern', +'CDLTRISTAR':'Tristar Pattern', +'CDLUNIQUE3RIVER':'Unique 3 River', +'CDLUPSIDEGAP2CROWS':'Upside Gap Two Crows', +'CDLXSIDEGAP3METHODS':'Upside/Downside Gap Three Methods' +} + +Company_Name ={ +"NIFTY 50" :"^NSEI", +"NIFTY BANK" : "^NSEBANK", +"INDIA VIX" : "^INDIAVIX", +"ADANI ENTERPRISES ":"ADANIENT.NS", +"ADANI PORTS AND SPECIAL ECONOMIC ZONE ":"ADANIPORTS.NS", +"APOLLO HOSPITALS ENTERPRISE ":"APOLLOHOSP.NS", +"ASIAN PAINTS ":"ASIANPAINT.NS", +"Axis Bank ":"AXISBANK.NS", +"MARUTI SUZUKI INDIA ":"MARUTI.NS", +"BAJAJ FINANCE ":"BAJFINANCE.NS", +"Bajaj Finserv ":"BAJAJFINSV.NS", +"BHARAT PETROLEUM CORPORATION ":"BPCL.NS", +"Bharti Airtel ":"BHARTIARTL.NS", # change +"BRITANNIA INDUSTRIES LTD" :"BRITANNIA.NS", +"CIPLA ":"CIPLA.NS", +"COAL INDIA LTD " :"COALINDIA.NS", +"DIVI'S LABORATORIES ":"DIVISLAB.NS", +"DR.REDDY'S LABORATORIES LTD ":"DRREDDY.NS", +"EICHER MOTORS ":"EICHERMOT.NS", +"GRASIM INDUSTRIES LTD ":"GRASIM.NS", +"HCL TECHNOLOGIES ":"HCLTECH.NS", +"HDFC BANK ":"HDFCBANK.NS", +"HDFC LIFE INSURANCE COMPANY ":"HDFCLIFE.NS", +"Hero MotoCorp ":"HEROMOTOCO.NS", +"HINDALCO INDUSTRIES ":"HINDALCO.NS", +"HINDUSTAN UNILEVER ":"HINDUNILVR.NS", +"HOUSING DEVELOPMENT FINANCE CORPORATION ":"HDFC.NS", +"ICICI BANK ":"ICICIBANK.NS", +"ITC ":"ITC.NS", +"INDUSIND BANK LTD. ":"INDUSINDBK.NS", +"INFOSYS ":"INFY.NS", +"JSW Steel ":"JSWSTEEL.NS", +"KOTAK MAHINDRA BANK ":"KOTAKBANK.NS", +"LARSEN AND TOUBRO ":"LT.NS", +"MAHINDRA AND MAHINDRA ":"M&M.NS", +"MARUTI SUZUKI INDIA ":"MARUTI.NS", +"NTPC ":"NTPC.NS", +"NESTLE INDIA ":"NESTLEIND.NS", +"OIL AND NATURAL GAS CORPORATION ":"ONGC.NS", +"POWER GRID CORPORATION OF INDIA ":"POWERGRID.NS", +"RELIANCE INDUSTRIES ":"RELIANCE.NS", #cahnged +"SBI LIFE INSURANCE COMPANY ":"SBILIFE.NS", +"SBI":"SBIN.NS", +"SUN PHARMACEUTICAL INDUSTRIES ":"SUNPHARMA.NS", +"TATA CONSULTANCY SERVICES ":"TCS.NS", +"TATA CONSUMER PRODUCTS ":"TATACONSUM.NS", +"TATA MOTORS ":"TATAMTRDVR.NS", +"TATA STEEL ":"TATASTEEL.NS", +"TECH MAHINDRA ":"TECHM.NS", +"TITAN COMPANY ":"TITAN.NS", +"UPL ":"UPL.NS", +"ULTRATECH CEMENT ":"ULTRACEMCO.NS", +"WIPRO ":"WIPRO.NS" +} diff --git a/News_App/requirements.txt b/News_App/requirements.txt new file mode 100644 index 00000000000..992be98b105 --- /dev/null +++ b/News_App/requirements.txt @@ -0,0 +1,6 @@ +solara == 1.19.0 +Flask +gunicorn ==21.2.0 +simple-websocket +flask-sock +yfinance \ No newline at end of file From 4c34216e048e2e7bc5a509f8d7f86e677e408f7f Mon Sep 17 00:00:00 2001 From: Rahul Chauhan <113838908+Rjchauhan18@users.noreply.github.com> Date: Mon, 23 Oct 2023 10:58:47 +0530 Subject: [PATCH 20/44] Update README.md --- News_App/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/News_App/README.md b/News_App/README.md index dd2590a9a24..26d138072cd 100644 --- a/News_App/README.md +++ b/News_App/README.md @@ -1,10 +1,10 @@ ## News App -- I have create News app using python solara framework and yfinace for getting news. +- I have create News app using python solara framework and yfinace for getting news of stocks. Steps to run the app: -1. Download the folder of News app or clone the whole repositery and go to the `python-beginner-projects/projects/News_App` and Install all the requirements +1. Clone the repositery and go to the `News_App` and Install all the requirements ``` pip install -r requirements.txt @@ -14,4 +14,4 @@ pip install -r requirements.txt ``` solara run Newsapp.py -``` \ No newline at end of file +``` From 77b464c6fb859b6f5add91f05b9b8a95e7392591 Mon Sep 17 00:00:00 2001 From: Rahul Chauhan <113838908+Rjchauhan18@users.noreply.github.com> Date: Mon, 23 Oct 2023 11:10:57 +0530 Subject: [PATCH 21/44] Update Newsapp.py --- News_App/Newsapp.py | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/News_App/Newsapp.py b/News_App/Newsapp.py index 2a19a45cac5..0f3f976e9fa 100644 --- a/News_App/Newsapp.py +++ b/News_App/Newsapp.py @@ -12,12 +12,10 @@ def News(symbol): get_Data = yf.Ticker(symbol) - # msft.news - + #news section try: NEWS = get_Data.news - # sr.Markdown(f"{NEWS}") sr.Markdown(f"# News of {v.value} :") for i in range(len(NEWS)): sr.Markdown("\n********************************\n") @@ -36,7 +34,7 @@ def News(symbol): except Exception as e: sr.Markdown(e) sr.Markdown("No news available") -# News(select) + @@ -48,26 +46,12 @@ def Page(): with sr.Column() as main: with sr.Sidebar(): sr.Markdown("## **stock Analysis**") - # sr.SliderInt(label="Ideal for placing controls") - # sr.header("**srock Analysis**") sr.Select("Select stock",value=v,values=company) select=Company_Name.get(v.value) - # sr.Text(select_company) - # sr.Info("I'm in the main content area, put your main content here") - News(select) - # sr.FigurePlotly(qs.plots.daily_returns(ITC,benchmark="US")) return main - - -# @app.route("/") -# def hello_world(): -# return "

Hello, World!

" - -# if __name__=="__main__": -# app.run(debug=False) \ No newline at end of file From 82507bff5bb3bbf46c2b63e785914ddf4165464b Mon Sep 17 00:00:00 2001 From: Alisha Parveen <139856223+Alisha-786@users.noreply.github.com> Date: Mon, 23 Oct 2023 18:28:10 +0530 Subject: [PATCH 22/44] Create mergesort_linkedlist.py --- Sorting Algorithims/mergesort_linkedlist.py | 77 +++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 Sorting Algorithims/mergesort_linkedlist.py diff --git a/Sorting Algorithims/mergesort_linkedlist.py b/Sorting Algorithims/mergesort_linkedlist.py new file mode 100644 index 00000000000..429684b6c0c --- /dev/null +++ b/Sorting Algorithims/mergesort_linkedlist.py @@ -0,0 +1,77 @@ +from __future__ import annotations + +class Node: + def __init__(self, data: int) -> None: + self.data = data + self.next = None + +class LinkedList: + def __init__(self): + self.head = None + + def insert(self, new_data: int) -> None: + new_node = Node(new_data) + new_node.next = self.head + self.head = new_node + + def printLL(self) -> None: + temp = self.head + if temp == None: + return 'Linked List is empty' + while temp.next: + print(temp.data, '->', end='') + temp = temp.next + print(temp.data) + return + +# Merge two sorted linked lists +def merge(left, right): + if not left: + return right + if not right: + return left + + if left.data < right.data: + result = left + result.next = merge(left.next, right) + else: + result = right + result.next = merge(left, right.next) + + return result + +# Merge sort for linked list +def merge_sort(head): + if not head or not head.next: + return head + + # Find the middle of the list + slow = head + fast = head.next + while fast and fast.next: + slow = slow.next + fast = fast.next.next + + left = head + right = slow.next + slow.next = None + + left = merge_sort(left) + right = merge_sort(right) + + return merge(left, right) + +if __name__ == "__main__": + ll = LinkedList() + print("Enter the space-separated values of numbers to be inserted in the linked list prompted below:") + arr = list(map(int, input().split())) + for num in arr: + ll.insert(num) + + print("Linked list before sorting:") + ll.printLL() + + ll.head = merge_sort(ll.head) + + print('Linked list after sorting:') + ll.printLL() From 0153486112bb21324a93147d81746bb159ad5a0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 18:11:57 +0000 Subject: [PATCH 23/44] Bump solara from 1.19.0 to 1.22.0 Bumps [solara](https://github.com/widgetti/solara) from 1.19.0 to 1.22.0. - [Changelog](https://github.com/widgetti/solara/blob/master/CHANGELOG.md) - [Commits](https://github.com/widgetti/solara/compare/v1.19.0...v1.22.0) --- updated-dependencies: - dependency-name: solara dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- News_App/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/News_App/requirements.txt b/News_App/requirements.txt index 992be98b105..fc3a139b2d4 100644 --- a/News_App/requirements.txt +++ b/News_App/requirements.txt @@ -1,4 +1,4 @@ -solara == 1.19.0 +solara == 1.22.0 Flask gunicorn ==21.2.0 simple-websocket From b03d4808d69da2a0d76d80beee5a0ac5d32c39eb Mon Sep 17 00:00:00 2001 From: Alisha Parveen <139856223+Alisha-786@users.noreply.github.com> Date: Tue, 24 Oct 2023 13:23:36 +0530 Subject: [PATCH 24/44] Create heapsort_linkedlist.py --- Sorting Algorithims/heapsort_linkedlist.py | 82 ++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 Sorting Algorithims/heapsort_linkedlist.py diff --git a/Sorting Algorithims/heapsort_linkedlist.py b/Sorting Algorithims/heapsort_linkedlist.py new file mode 100644 index 00000000000..7e9584077e6 --- /dev/null +++ b/Sorting Algorithims/heapsort_linkedlist.py @@ -0,0 +1,82 @@ +class Node: + def __init__(self, data): + self.data = data + self.next = None + +class LinkedList: + def __init__(self): + self.head = None + + def push(self, data): + new_node = Node(data) + new_node.next = self.head + self.head = new_node + + def print_list(self): + current = self.head + while current: + print(current.data, end=" -> ") + current = current.next + print("None") + + def heapify(self, n, i): + largest = i + left = 2 * i + 1 + right = 2 * i + 2 + + current = self.head + for _ in range(i): + current = current.next + + if left < n and current.data < current.next.data: + largest = left + + if right < n and current.data < current.next.data: + largest = right + + if largest != i: + self.swap(i, largest) + self.heapify(n, largest) + + def swap(self, i, j): + current_i = self.head + current_j = self.head + + for _ in range(i): + current_i = current_i.next + + for _ in range(j): + current_j = current_j.next + + current_i.data, current_j.data = current_j.data, current_i.data + + def heap_sort(self): + n = 0 + current = self.head + while current: + n += 1 + current = current.next + + for i in range(n // 2 - 1, -1, -1): + self.heapify(n, i) + + for i in range(n - 1, 0, -1): + self.swap(0, i) + self.heapify(i, 0) + +# Example usage: +linked_list = LinkedList() +linked_list.push(12) +linked_list.push(11) +linked_list.push(13) +linked_list.push(5) +linked_list.push(6) +linked_list.push(7) + +print("Original Linked List:") +linked_list.print_list() + +linked_list.heap_sort() + +print("Sorted Linked List:") +linked_list.print_list() From 5c7f596057cd67a77ad09fc201a408b4e69fad14 Mon Sep 17 00:00:00 2001 From: Harshavardhan Bajoria <62978274+HVbajoria@users.noreply.github.com> Date: Tue, 24 Oct 2023 21:27:15 +0530 Subject: [PATCH 25/44] Created AI Tic Tac Toe Game --- AI Game/Tic-Tac-Toe-AI/tictactoe.py | 102 ++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 AI Game/Tic-Tac-Toe-AI/tictactoe.py diff --git a/AI Game/Tic-Tac-Toe-AI/tictactoe.py b/AI Game/Tic-Tac-Toe-AI/tictactoe.py new file mode 100644 index 00000000000..15ccee79e9b --- /dev/null +++ b/AI Game/Tic-Tac-Toe-AI/tictactoe.py @@ -0,0 +1,102 @@ +import tkinter as tk +from tkinter import messagebox +import random + +def check_winner(board, player): + # Check rows, columns, and diagonals for a win + for i in range(3): + if all(board[i][j] == player for j in range(3)) or all(board[j][i] == player for j in range(3)): + return True + if all(board[i][i] == player for i in range(3)) or all(board[i][2 - i] == player for i in range(3)): + return True + return False + +def is_board_full(board): + return all(all(cell != ' ' for cell in row) for row in board) + +def minimax(board, depth, is_maximizing): + if check_winner(board, 'X'): + return -1 + if check_winner(board, 'O'): + return 1 + if is_board_full(board): + return 0 + + if is_maximizing: + max_eval = float('-inf') + for i in range(3): + for j in range(3): + if board[i][j] == ' ': + board[i][j] = 'O' + eval = minimax(board, depth + 1, False) + board[i][j] = ' ' + max_eval = max(max_eval, eval) + return max_eval + else: + min_eval = float('inf') + for i in range(3): + for j in range(3): + if board[i][j] == ' ': + board[i][j] = 'X' + eval = minimax(board, depth + 1, True) + board[i][j] = ' ' + min_eval = min(min_eval, eval) + return min_eval + +def best_move(board): + best_val = float('-inf') + best_move = None + + for i in range(3): + for j in range(3): + if board[i][j] == ' ': + board[i][j] = 'O' + move_val = minimax(board, 0, False) + board[i][j] = ' ' + if move_val > best_val: + best_val = move_val + best_move = (i, j) + + return best_move + +def make_move(row, col): + if board[row][col] == ' ': + board[row][col] = 'X' + buttons[row][col].config(text='X') + if check_winner(board, 'X'): + messagebox.showinfo("Tic-Tac-Toe", "You win!") + root.quit() + elif is_board_full(board): + messagebox.showinfo("Tic-Tac-Toe", "It's a draw!") + root.quit() + else: + ai_move() + else: + messagebox.showerror("Error", "Invalid move") + +def ai_move(): + row, col = best_move(board) + board[row][col] = 'O' + buttons[row][col].config(text='O') + if check_winner(board, 'O'): + messagebox.showinfo("Tic-Tac-Toe", "AI wins!") + root.quit() + elif is_board_full(board): + messagebox.showinfo("Tic-Tac-Toe", "It's a draw!") + root.quit() + +root = tk.Tk() +root.title("Tic-Tac-Toe") + +board = [[' ' for _ in range(3)] for _ in range(3] +buttons = [] + +for i in range(3): + row_buttons = [] + for j in range(3): + button = tk.Button(root, text=' ', font=('normal', 30), width=5, height=2, command=lambda row=i, col=j: make_move(row, col)) + button.grid(row=i, column=j) + row_buttons.append(button) + buttons.append(row_buttons) + +root.mainloop() From a6947c9bc519daf039f00ba2873ed12d8e2253f4 Mon Sep 17 00:00:00 2001 From: Harshavardhan Bajoria <62978274+HVbajoria@users.noreply.github.com> Date: Tue, 24 Oct 2023 21:29:52 +0530 Subject: [PATCH 26/44] Added Project to the list --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 97687e178a8..334230ef634 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,8 @@ Feel free to explore the scripts and use them for your learning and automation n 38. [Images Downloader](https://git.io/JvnJh) - Download images from webpages on Unix-based systems. 39. [space_invader.py.py](https://github.com/meezan-mallick/space_invader_game) - Classical 2D space invader game to recall your childhood memories. 40. [Test Case Generator](https://github.com/Tanmay-901/test-case-generator/blob/master/test_case.py) - Generate different types of test cases with a clean and friendly UI, used in competitive programming and software testing. +41. [Titc-Tac-Toe With AI](https://github.com/HVbajoria/Python/tree/master/AI%20Game/Tic-Tac-Toe-AI) - Play Tic-Tac-Toe Game with AI
-_**Note**: The content in this repository belongs to the respective authors and creators. I'm just providing a formatted README.md for better presentation._ +_**Note**: The content in this repository belongs to the respective authors and creators. I'm just providing a formatted README.md for a better presentation._ From bc3fd39e5e71bebf6266534115e1666cd8876c27 Mon Sep 17 00:00:00 2001 From: Ilia <81512402+ilia-abbasi@users.noreply.github.com> Date: Tue, 24 Oct 2023 19:47:23 +0330 Subject: [PATCH 27/44] Update calculator.py Prioritized lowering the input --- calculator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/calculator.py b/calculator.py index b12986aa7e6..b0ef5dca8dd 100644 --- a/calculator.py +++ b/calculator.py @@ -37,6 +37,9 @@ def calc(term): purpose: This function is the actual calculator and the heart of the application """ + # This part is for reading and converting function expressions. + term = term.lower() + # This part is for reading and converting arithmetic terms. term = term.replace(" ", "") term = term.replace("^", "**") @@ -61,9 +64,6 @@ def calc(term): "e", ] - # This part is for reading and converting function expressions. - term = term.lower() - for func in functions: if func in term: withmath = "math." + func From 9991d6aff3e38814e69ce42409fcbd688dd83182 Mon Sep 17 00:00:00 2001 From: Harshavardhan Bajoria <62978274+HVbajoria@users.noreply.github.com> Date: Wed, 25 Oct 2023 14:54:54 +0530 Subject: [PATCH 28/44] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 334230ef634..015f275a68c 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,6 @@ Feel free to explore the scripts and use them for your learning and automation n 38. [Images Downloader](https://git.io/JvnJh) - Download images from webpages on Unix-based systems. 39. [space_invader.py.py](https://github.com/meezan-mallick/space_invader_game) - Classical 2D space invader game to recall your childhood memories. 40. [Test Case Generator](https://github.com/Tanmay-901/test-case-generator/blob/master/test_case.py) - Generate different types of test cases with a clean and friendly UI, used in competitive programming and software testing. -41. [Titc-Tac-Toe With AI](https://github.com/HVbajoria/Python/tree/master/AI%20Game/Tic-Tac-Toe-AI) - Play Tic-Tac-Toe Game with AI -
_**Note**: The content in this repository belongs to the respective authors and creators. I'm just providing a formatted README.md for a better presentation._ From c62ef6a6c28902ac97de668a5e5cd53b47690568 Mon Sep 17 00:00:00 2001 From: Harshavardhan Bajoria <62978274+HVbajoria@users.noreply.github.com> Date: Wed, 25 Oct 2023 14:57:23 +0530 Subject: [PATCH 29/44] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 015f275a68c..3d60e43bbf1 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ Feel free to explore the scripts and use them for your learning and automation n 38. [Images Downloader](https://git.io/JvnJh) - Download images from webpages on Unix-based systems. 39. [space_invader.py.py](https://github.com/meezan-mallick/space_invader_game) - Classical 2D space invader game to recall your childhood memories. 40. [Test Case Generator](https://github.com/Tanmay-901/test-case-generator/blob/master/test_case.py) - Generate different types of test cases with a clean and friendly UI, used in competitive programming and software testing. +
-_**Note**: The content in this repository belongs to the respective authors and creators. I'm just providing a formatted README.md for a better presentation._ +_**Note**: The content in this repository belongs to the respective authors and creators. I'm just providing formatted README.md for a better presentation._ From 2dd08f344561ab691f39b10c637cd34d4d1e4887 Mon Sep 17 00:00:00 2001 From: Harshavardhan Bajoria <62978274+HVbajoria@users.noreply.github.com> Date: Wed, 25 Oct 2023 14:57:58 +0530 Subject: [PATCH 30/44] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d60e43bbf1..97687e178a8 100644 --- a/README.md +++ b/README.md @@ -55,4 +55,4 @@ Feel free to explore the scripts and use them for your learning and automation n
-_**Note**: The content in this repository belongs to the respective authors and creators. I'm just providing formatted README.md for a better presentation._ +_**Note**: The content in this repository belongs to the respective authors and creators. I'm just providing a formatted README.md for better presentation._ From f9e058abe97ac051a68e3f7568e3202c85f14341 Mon Sep 17 00:00:00 2001 From: Varun Dhand <110025628+varundhand@users.noreply.github.com> Date: Wed, 25 Oct 2023 23:54:37 +0530 Subject: [PATCH 31/44] FIx: typo in login.py --- login.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/login.py b/login.py index 791c1d94247..8095f4f4e54 100644 --- a/login.py +++ b/login.py @@ -20,7 +20,7 @@ def logo(): print("\033[1;36;49m") -# This is Login Funtion +# This is Login Function def login(): # for clear the screen os.system("clear") From b324c90e67433ba28bd14fd900e8588ed6aa5ca3 Mon Sep 17 00:00:00 2001 From: Indrani Som Date: Sat, 28 Oct 2023 11:51:05 +0530 Subject: [PATCH 32/44] added a Tic-Tac-Toe Game --- TIC_TAC_TOE/index.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 TIC_TAC_TOE/index.py diff --git a/TIC_TAC_TOE/index.py b/TIC_TAC_TOE/index.py new file mode 100644 index 00000000000..7e494d0e700 --- /dev/null +++ b/TIC_TAC_TOE/index.py @@ -0,0 +1,46 @@ +def print_board(board): + for row in board: + print(" | ".join(row)) + print("-" * 9) + +def check_winner(board, player): + for i in range(3): + # Check rows and columns + if all(board[i][j] == player for j in range(3)) or all(board[j][i] == player for j in range(3)): + return True + # Check diagonals + if all(board[i][i] == player for i in range(3)) or all(board[i][2 - i] == player for i in range(3)): + return True + return False + +def is_full(board): + return all(cell != " " for row in board for cell in row) + +def main(): + board = [[" " for _ in range(3)] for _ in range(3)] + player = "X" + + while True: + print_board(board) + row = int(input(f"Player {player}, enter the row (0, 1, 2): ")) + col = int(input(f"Player {player}, enter the column (0, 1, 2): ")) + + if 0 <= row < 3 and 0 <= col < 3 and board[row][col] == " ": + board[row][col] = player + + if check_winner(board, player): + print_board(board) + print(f"Player {player} wins!") + break + + if is_full(board): + print_board(board) + print("It's a draw!") + break + + player = "O" if player == "X" else "X" + else: + print("Invalid move. Try again.") + +if __name__ == "__main__": + main() From 56ee8746ad814c1a4bf5ebd71f1b81576c9d04b6 Mon Sep 17 00:00:00 2001 From: Debmalya Sadhukhan <131870160+deBmalooo@users.noreply.github.com> Date: Sat, 28 Oct 2023 16:20:06 +0530 Subject: [PATCH 33/44] final commit --- quiz_game.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 quiz_game.py diff --git a/quiz_game.py b/quiz_game.py new file mode 100644 index 00000000000..c1ffd6696b0 --- /dev/null +++ b/quiz_game.py @@ -0,0 +1,32 @@ +print('Welcome to AskPython Quiz') +answer=input('Are you ready to play the Quiz ? (yes/no) :') +score=0 +total_questions=3 + +if answer.lower()=='yes': + answer=input('Question 1: What is your Favourite programming language?') + if answer.lower()=='python': + score += 1 + print('correct') + else: + print('Wrong Answer :(') + + + answer=input('Question 2: Do you follow any author on AskPython? ') + if answer.lower()=='yes': + score += 1 + print('correct') + else: + print('Wrong Answer :(') + + answer=input('Question 3: What is the name of your favourite website for learning Python?') + if answer.lower()=='askpython': + score += 1 + print('correct') + else: + print('Wrong Answer :(') + +print('Thankyou for Playing this small quiz game, you attempted',score,"questions correctly!") +mark=(score/total_questions)*100 +print('Marks obtained:',mark) +print('BYE!') \ No newline at end of file From 6b369962aca0cd22e15967e2838a6584ee2e3bf0 Mon Sep 17 00:00:00 2001 From: Indrani Som Date: Sat, 28 Oct 2023 16:49:01 +0530 Subject: [PATCH 34/44] added a number guessing game --- numberguessinggame/index.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 numberguessinggame/index.py diff --git a/numberguessinggame/index.py b/numberguessinggame/index.py new file mode 100644 index 00000000000..3116af47dce --- /dev/null +++ b/numberguessinggame/index.py @@ -0,0 +1,28 @@ +import random + +def number_guessing_game(): + + secret_number = random.randint(1, 100) + attempts = 0 + + print("Welcome to the Number Guessing Game!") + print("I'm thinking of a number between 1 and 100.") + + while True: + try: + guess = int(input("Your guess: ")) + attempts += 1 + + if guess < secret_number: + print("Too low! Try again.") + elif guess > secret_number: + print("Too high! Try again.") + else: + print(f"Congratulations! You guessed the number {secret_number} in {attempts} attempts!") + break + + except ValueError: + print("Please enter a valid number.") + +if __name__ == "__main__": + number_guessing_game() From 429f1bdb67867b4ff5e806cc9e01ed85c7d5eb23 Mon Sep 17 00:00:00 2001 From: "ahmadibtsam07@gmail.com" Date: Sun, 29 Oct 2023 01:23:23 +0500 Subject: [PATCH 35/44] added function to extract thumbnail from videos --- extract_thumbnail_from_video.py | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 extract_thumbnail_from_video.py diff --git a/extract_thumbnail_from_video.py b/extract_thumbnail_from_video.py new file mode 100644 index 00000000000..76ca3b43eb7 --- /dev/null +++ b/extract_thumbnail_from_video.py @@ -0,0 +1,39 @@ +import cv2 +import os + +def extract_thumbnail(video_path, frame_size): + """ + Extracts a thumbnail frame from a video and saves it as an image file. + + Args: + video_path (str): The path to the input video file. + frame_size (tuple): A tuple containing the desired dimensions (width, height) for the thumbnail frame. + + Raises: + Exception: If the function fails to extract a frame from the video. + + The function opens the specified video file, seeks to the middle frame, + resizes the frame to the specified dimensions, and saves it as an image + file with a filename derived from the video's base name. + + Example: + extract_thumbnail('my_video.mp4', (320, 240)) + + Required Packages: + cv2 (pip install cv2) + + This function is useful for generating thumbnail images from videos. + """ + video_capture = cv2.VideoCapture(video_path) # Open the video file for reading + total_frames = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT)) # Get the total number of frames in the video + middle_frame_index = total_frames // 2 # Calculate the index of the middle frame + video_capture.set(cv2.CAP_PROP_POS_FRAMES, middle_frame_index) # Seek to the middle frame + success, frame = video_capture.read() # Read the middle frame + video_capture.release() # Release the video capture object + + if success: + frame = cv2.resize(frame, frame_size) # Resize the frame to the specified dimensions + thumbnail_filename = f"{os.path.basename(video_path)}_thumbnail.jpg" # Create a filename for the thumbnail + cv2.imwrite(thumbnail_filename, frame) # Save the thumbnail frame as an image + else: + raise Exception("Could not extract frame") # Raise an exception if frame extraction fails From 080e647f251ccd529bfbdbd1321af1be5d22a5af Mon Sep 17 00:00:00 2001 From: Hemant <135449755+Hemant-Dua@users.noreply.github.com> Date: Sun, 29 Oct 2023 23:40:17 +0530 Subject: [PATCH 36/44] Update hand_motion_recognizer.py Got rid of unused libraries --- Hand-Motion-Detection/hand_motion_recognizer.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/Hand-Motion-Detection/hand_motion_recognizer.py b/Hand-Motion-Detection/hand_motion_recognizer.py index 9e9db13ce9e..59efb53c8ef 100644 --- a/Hand-Motion-Detection/hand_motion_recognizer.py +++ b/Hand-Motion-Detection/hand_motion_recognizer.py @@ -1,8 +1,5 @@ import mediapipe as mp import cv2 -import numpy as np -import uuid -import os mp_drawing = mp.solutions.drawing_utils mp_hands = mp.solutions.hands From b8fb78322b711308df8438299c8aab43e0e2d031 Mon Sep 17 00:00:00 2001 From: "ahmadibtsam07@gmail.com" Date: Mon, 30 Oct 2023 23:07:18 +0500 Subject: [PATCH 37/44] added readme --- Extract Thumbnail from video/README.md | 49 +++++++++++++++++++ .../extract_thumbnail_from_video.py | 0 2 files changed, 49 insertions(+) create mode 100644 Extract Thumbnail from video/README.md rename extract_thumbnail_from_video.py => Extract Thumbnail from video/extract_thumbnail_from_video.py (100%) diff --git a/Extract Thumbnail from video/README.md b/Extract Thumbnail from video/README.md new file mode 100644 index 00000000000..2726afa84dd --- /dev/null +++ b/Extract Thumbnail from video/README.md @@ -0,0 +1,49 @@ +# Thumbnail Extractor + +This Python function extracts a thumbnail frame from a video and saves it as an image file. It utilizes the OpenCV library to perform these operations. This README provides an overview of the function, its usage, and the required packages. + +## Table of Contents +- [Function Description](#function-description) +- [Usage](#usage) +- [Required Packages](#required-packages) + +## Function Description + +The `extract_thumbnail` function takes two parameters: + +- `video_path` (str): The path to the input video file. +- `frame_size` (tuple): A tuple containing the desired dimensions (width, height) for the thumbnail frame. + +The function will raise an `Exception` if it fails to extract a frame from the video. + +### Function Logic + +1. The function opens the specified video file using OpenCV. +2. It seeks to the middle frame by calculating the middle frame index. +3. The frame is resized to the specified dimensions. +4. The resized frame is saved as an image file with a filename derived from the video's base name. + +## Usage + +Here's an example of how to use the function: + +```python +from thumbnail_extractor import extract_thumbnail + +# Extract a thumbnail from 'my_video.mp4' with dimensions (320, 240) +extract_thumbnail('my_video.mp4', (320, 240)) +# Replace 'my_video.mp4' with the path to your own video file and (320, 240) with your desired thumbnail dimensions. + +## Required Packages +``` +To use this function, you need the following package: + +- **OpenCV (cv2)**: You can install it using `pip`: + + ```shell + pip install opencv-python + ``` + +This function is useful for generating thumbnail images from videos. It simplifies the process of creating video thumbnails for various applications. + + diff --git a/extract_thumbnail_from_video.py b/Extract Thumbnail from video/extract_thumbnail_from_video.py similarity index 100% rename from extract_thumbnail_from_video.py rename to Extract Thumbnail from video/extract_thumbnail_from_video.py From 24a682c8163f3b1ae9f01e19c778cca5abc2c14c Mon Sep 17 00:00:00 2001 From: "ahmadibtsam07@gmail.com" Date: Mon, 30 Oct 2023 23:13:14 +0500 Subject: [PATCH 38/44] added link in main readme --- .../README.md | 0 .../extract_thumbnail_from_video.py | 0 README.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename {Extract Thumbnail from video => ExtractThumbnailFromVideo}/README.md (100%) rename {Extract Thumbnail from video => ExtractThumbnailFromVideo}/extract_thumbnail_from_video.py (100%) diff --git a/Extract Thumbnail from video/README.md b/ExtractThumbnailFromVideo/README.md similarity index 100% rename from Extract Thumbnail from video/README.md rename to ExtractThumbnailFromVideo/README.md diff --git a/Extract Thumbnail from video/extract_thumbnail_from_video.py b/ExtractThumbnailFromVideo/extract_thumbnail_from_video.py similarity index 100% rename from Extract Thumbnail from video/extract_thumbnail_from_video.py rename to ExtractThumbnailFromVideo/extract_thumbnail_from_video.py diff --git a/README.md b/README.md index 97687e178a8..4d5e575cae1 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ Feel free to explore the scripts and use them for your learning and automation n 38. [Images Downloader](https://git.io/JvnJh) - Download images from webpages on Unix-based systems. 39. [space_invader.py.py](https://github.com/meezan-mallick/space_invader_game) - Classical 2D space invader game to recall your childhood memories. 40. [Test Case Generator](https://github.com/Tanmay-901/test-case-generator/blob/master/test_case.py) - Generate different types of test cases with a clean and friendly UI, used in competitive programming and software testing. - +41. [Extract Thumbnail From Video](https://github.com/geekcomputers/Python/tree/ExtractThumbnailFromVideo) - Extract Thumbnail from video files
_**Note**: The content in this repository belongs to the respective authors and creators. I'm just providing a formatted README.md for better presentation._ From 1273a118ea8f5bdced58c68a1253b501c8a2f8b3 Mon Sep 17 00:00:00 2001 From: Kevin Liao Date: Mon, 30 Oct 2023 16:35:10 -0400 Subject: [PATCH 39/44] Fixed syntax error in TicTacToe file --- AI Game/Tic-Tac-Toe-AI/tictactoe.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/AI Game/Tic-Tac-Toe-AI/tictactoe.py b/AI Game/Tic-Tac-Toe-AI/tictactoe.py index 15ccee79e9b..6157ff6efb0 100644 --- a/AI Game/Tic-Tac-Toe-AI/tictactoe.py +++ b/AI Game/Tic-Tac-Toe-AI/tictactoe.py @@ -1,5 +1,5 @@ -import tkinter as tk -from tkinter import messagebox +import tkinter as tk #provides a library of basic elements of GUI widgets +from tkinter import messagebox #provides a different set of dialogues that are used to display message boxes import random def check_winner(board, player): @@ -19,30 +19,31 @@ def minimax(board, depth, is_maximizing): return -1 if check_winner(board, 'O'): return 1 - if is_board_full(board): + if is_board_full(board): #if game is full, terminate return 0 - if is_maximizing: + if is_maximizing: #recursive approach that fills board with Os max_eval = float('-inf') for i in range(3): for j in range(3): if board[i][j] == ' ': board[i][j] = 'O' - eval = minimax(board, depth + 1, False) + eval = minimax(board, depth + 1, False) #recursion board[i][j] = ' ' max_eval = max(max_eval, eval) return max_eval - else: + else: #recursive approach that fills board with Xs min_eval = float('inf') for i in range(3): for j in range(3): if board[i][j] == ' ': board[i][j] = 'X' - eval = minimax(board, depth + 1, True) + eval = minimax(board, depth + 1, True) #recursion board[i][j] = ' ' min_eval = min(min_eval, eval) return min_eval +#determines the best move for the current player and returns a tuple representing the position def best_move(board): best_val = float('-inf') best_move = None @@ -74,6 +75,7 @@ def make_move(row, col): else: messagebox.showerror("Error", "Invalid move") +#AI's turn to play def ai_move(): row, col = best_move(board) board[row][col] = 'O' @@ -88,7 +90,7 @@ def ai_move(): root = tk.Tk() root.title("Tic-Tac-Toe") -board = [[' ' for _ in range(3)] for _ in range(3] +board = [[' ' for _ in range(3)] for _ in range(3)] buttons = [] for i in range(3): From 60078fe99e815df9fbc0dcd5c2b0745f297cf200 Mon Sep 17 00:00:00 2001 From: DIOD Date: Wed, 1 Nov 2023 16:48:49 +0100 Subject: [PATCH 40/44] Added Industrial_developed_hangman --- Industrial_developed_hangman/Makefile | 14 + Industrial_developed_hangman/README.md | 7 + Industrial_developed_hangman/poetry.lock | 1235 +++++++++++++++++ Industrial_developed_hangman/pyproject.toml | 35 + Industrial_developed_hangman/pytest.ini | 5 + Industrial_developed_hangman/setup.cfg | 48 + .../src/hangman/__init__.py | 0 .../src/hangman/main.py | 170 +++ 8 files changed, 1514 insertions(+) create mode 100644 Industrial_developed_hangman/Makefile create mode 100644 Industrial_developed_hangman/README.md create mode 100644 Industrial_developed_hangman/poetry.lock create mode 100644 Industrial_developed_hangman/pyproject.toml create mode 100644 Industrial_developed_hangman/pytest.ini create mode 100644 Industrial_developed_hangman/setup.cfg create mode 100644 Industrial_developed_hangman/src/hangman/__init__.py create mode 100644 Industrial_developed_hangman/src/hangman/main.py diff --git a/Industrial_developed_hangman/Makefile b/Industrial_developed_hangman/Makefile new file mode 100644 index 00000000000..e4e05f18fb2 --- /dev/null +++ b/Industrial_developed_hangman/Makefile @@ -0,0 +1,14 @@ +lint: + poetry run isort src tests + poetry run flake8 src tests + poetry run mypy src + poetry run mypy tests + +test: + poetry run pytest + +build: + python src/hangman/main.py +install: + pip install poetry + poetry install \ No newline at end of file diff --git a/Industrial_developed_hangman/README.md b/Industrial_developed_hangman/README.md new file mode 100644 index 00000000000..60147752200 --- /dev/null +++ b/Industrial_developed_hangman/README.md @@ -0,0 +1,7 @@ +This is a simple game hangman + +to install dependencies got to repository "Industrial_developed_hangman" by `cd .\Industrial_developed_hangman\` and run `make install` + +to start it use `make build` command + +also makefile have lint command to lint source code \ No newline at end of file diff --git a/Industrial_developed_hangman/poetry.lock b/Industrial_developed_hangman/poetry.lock new file mode 100644 index 00000000000..99bcf936a62 --- /dev/null +++ b/Industrial_developed_hangman/poetry.lock @@ -0,0 +1,1235 @@ +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. + +[[package]] +name = "astor" +version = "0.8.1" +description = "Read/rewrite/write Python ASTs" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +files = [ + {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, + {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, +] + +[[package]] +name = "attrs" +version = "23.1.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] + +[[package]] +name = "bandit" +version = "1.7.5" +description = "Security oriented static analyser for python code." +optional = false +python-versions = ">=3.7" +files = [ + {file = "bandit-1.7.5-py3-none-any.whl", hash = "sha256:75665181dc1e0096369112541a056c59d1c5f66f9bb74a8d686c3c362b83f549"}, + {file = "bandit-1.7.5.tar.gz", hash = "sha256:bdfc739baa03b880c2d15d0431b31c658ffc348e907fe197e54e0389dd59e11e"}, +] + +[package.dependencies] +colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} +GitPython = ">=1.0.1" +PyYAML = ">=5.3.1" +rich = "*" +stevedore = ">=1.20.0" + +[package.extras] +test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "tomli (>=1.1.0)"] +toml = ["tomli (>=1.1.0)"] +yaml = ["PyYAML"] + +[[package]] +name = "beautifulsoup4" +version = "4.12.0" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.0-py3-none-any.whl", hash = "sha256:2130a5ad7f513200fae61a17abb5e338ca980fa28c439c0571014bc0217e9591"}, + {file = "beautifulsoup4-4.12.0.tar.gz", hash = "sha256:c5fceeaec29d09c84970e47c65f2f0efe57872f7cff494c9691a26ec0ff13234"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "certifi" +version = "2023.7.22" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, + {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "coverage" +version = "7.3.2" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "coverage-7.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf"}, + {file = "coverage-7.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9"}, + {file = "coverage-7.3.2-cp310-cp310-win32.whl", hash = "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f"}, + {file = "coverage-7.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611"}, + {file = "coverage-7.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c"}, + {file = "coverage-7.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312"}, + {file = "coverage-7.3.2-cp311-cp311-win32.whl", hash = "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640"}, + {file = "coverage-7.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2"}, + {file = "coverage-7.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836"}, + {file = "coverage-7.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a"}, + {file = "coverage-7.3.2-cp312-cp312-win32.whl", hash = "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb"}, + {file = "coverage-7.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed"}, + {file = "coverage-7.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738"}, + {file = "coverage-7.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76"}, + {file = "coverage-7.3.2-cp38-cp38-win32.whl", hash = "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92"}, + {file = "coverage-7.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a"}, + {file = "coverage-7.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce"}, + {file = "coverage-7.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083"}, + {file = "coverage-7.3.2-cp39-cp39-win32.whl", hash = "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce"}, + {file = "coverage-7.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f"}, + {file = "coverage-7.3.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637"}, + {file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "darglint" +version = "1.8.1" +description = "A utility for ensuring Google-style docstrings stay up to date with the source code." +optional = false +python-versions = ">=3.6,<4.0" +files = [ + {file = "darglint-1.8.1-py3-none-any.whl", hash = "sha256:5ae11c259c17b0701618a20c3da343a3eb98b3bc4b5a83d31cdd94f5ebdced8d"}, + {file = "darglint-1.8.1.tar.gz", hash = "sha256:080d5106df149b199822e7ee7deb9c012b49891538f14a11be681044f0bb20da"}, +] + +[[package]] +name = "docutils" +version = "0.20.1" +description = "Docutils -- Python Documentation Utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, +] + +[[package]] +name = "eradicate" +version = "2.3.0" +description = "Removes commented-out code." +optional = false +python-versions = "*" +files = [ + {file = "eradicate-2.3.0-py3-none-any.whl", hash = "sha256:2b29b3dd27171f209e4ddd8204b70c02f0682ae95eecb353f10e8d72b149c63e"}, + {file = "eradicate-2.3.0.tar.gz", hash = "sha256:06df115be3b87d0fc1c483db22a2ebb12bcf40585722810d809cc770f5031c37"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.1.3" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, + {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "flake8" +version = "6.1.0" +description = "the modular source code checker: pep8 pyflakes and co" +optional = false +python-versions = ">=3.8.1" +files = [ + {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, + {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, +] + +[package.dependencies] +mccabe = ">=0.7.0,<0.8.0" +pycodestyle = ">=2.11.0,<2.12.0" +pyflakes = ">=3.1.0,<3.2.0" + +[[package]] +name = "flake8-bandit" +version = "4.1.1" +description = "Automated security testing with bandit and flake8." +optional = false +python-versions = ">=3.6" +files = [ + {file = "flake8_bandit-4.1.1-py3-none-any.whl", hash = "sha256:4c8a53eb48f23d4ef1e59293657181a3c989d0077c9952717e98a0eace43e06d"}, + {file = "flake8_bandit-4.1.1.tar.gz", hash = "sha256:068e09287189cbfd7f986e92605adea2067630b75380c6b5733dab7d87f9a84e"}, +] + +[package.dependencies] +bandit = ">=1.7.3" +flake8 = ">=5.0.0" + +[[package]] +name = "flake8-broken-line" +version = "1.0.0" +description = "Flake8 plugin to forbid backslashes for line breaks" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "flake8_broken_line-1.0.0-py3-none-any.whl", hash = "sha256:96c964336024a5030dc536a9f6fb02aa679e2d2a6b35b80a558b5136c35832a9"}, + {file = "flake8_broken_line-1.0.0.tar.gz", hash = "sha256:e2c6a17f8d9a129e99c1320fce89b33843e2963871025c4c2bb7b8b8d8732a85"}, +] + +[package.dependencies] +flake8 = ">5" + +[[package]] +name = "flake8-bugbear" +version = "23.9.16" +description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." +optional = false +python-versions = ">=3.8.1" +files = [ + {file = "flake8-bugbear-23.9.16.tar.gz", hash = "sha256:90cf04b19ca02a682feb5aac67cae8de742af70538590509941ab10ae8351f71"}, + {file = "flake8_bugbear-23.9.16-py3-none-any.whl", hash = "sha256:b182cf96ea8f7a8595b2f87321d7d9b28728f4d9c3318012d896543d19742cb5"}, +] + +[package.dependencies] +attrs = ">=19.2.0" +flake8 = ">=6.0.0" + +[package.extras] +dev = ["coverage", "hypothesis", "hypothesmith (>=0.2)", "pre-commit", "pytest", "tox"] + +[[package]] +name = "flake8-commas" +version = "2.1.0" +description = "Flake8 lint for trailing commas." +optional = false +python-versions = "*" +files = [ + {file = "flake8-commas-2.1.0.tar.gz", hash = "sha256:940441ab8ee544df564ae3b3f49f20462d75d5c7cac2463e0b27436e2050f263"}, + {file = "flake8_commas-2.1.0-py2.py3-none-any.whl", hash = "sha256:ebb96c31e01d0ef1d0685a21f3f0e2f8153a0381430e748bf0bbbb5d5b453d54"}, +] + +[package.dependencies] +flake8 = ">=2" + +[[package]] +name = "flake8-comprehensions" +version = "3.14.0" +description = "A flake8 plugin to help you write better list/set/dict comprehensions." +optional = false +python-versions = ">=3.8" +files = [ + {file = "flake8_comprehensions-3.14.0-py3-none-any.whl", hash = "sha256:7b9d07d94aa88e62099a6d1931ddf16c344d4157deedf90fe0d8ee2846f30e97"}, + {file = "flake8_comprehensions-3.14.0.tar.gz", hash = "sha256:81768c61bfc064e1a06222df08a2580d97de10cb388694becaf987c331c6c0cf"}, +] + +[package.dependencies] +flake8 = ">=3.0,<3.2.0 || >3.2.0" + +[[package]] +name = "flake8-debugger" +version = "4.1.2" +description = "ipdb/pdb statement checker plugin for flake8" +optional = false +python-versions = ">=3.7" +files = [ + {file = "flake8-debugger-4.1.2.tar.gz", hash = "sha256:52b002560941e36d9bf806fca2523dc7fb8560a295d5f1a6e15ac2ded7a73840"}, + {file = "flake8_debugger-4.1.2-py3-none-any.whl", hash = "sha256:0a5e55aeddcc81da631ad9c8c366e7318998f83ff00985a49e6b3ecf61e571bf"}, +] + +[package.dependencies] +flake8 = ">=3.0" +pycodestyle = "*" + +[[package]] +name = "flake8-docstrings" +version = "1.7.0" +description = "Extension for flake8 which uses pydocstyle to check docstrings" +optional = false +python-versions = ">=3.7" +files = [ + {file = "flake8_docstrings-1.7.0-py2.py3-none-any.whl", hash = "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75"}, + {file = "flake8_docstrings-1.7.0.tar.gz", hash = "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af"}, +] + +[package.dependencies] +flake8 = ">=3" +pydocstyle = ">=2.1" + +[[package]] +name = "flake8-eradicate" +version = "1.5.0" +description = "Flake8 plugin to find commented out code" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "flake8_eradicate-1.5.0-py3-none-any.whl", hash = "sha256:18acc922ad7de623f5247c7d5595da068525ec5437dd53b22ec2259b96ce9d22"}, + {file = "flake8_eradicate-1.5.0.tar.gz", hash = "sha256:aee636cb9ecb5594a7cd92d67ad73eb69909e5cc7bd81710cf9d00970f3983a6"}, +] + +[package.dependencies] +attrs = "*" +eradicate = ">=2.0,<3.0" +flake8 = ">5" + +[[package]] +name = "flake8-isort" +version = "6.1.0" +description = "flake8 plugin that integrates isort ." +optional = false +python-versions = ">=3.8" +files = [ + {file = "flake8-isort-6.1.0.tar.gz", hash = "sha256:d4639343bac540194c59fb1618ac2c285b3e27609f353bef6f50904d40c1643e"}, +] + +[package.dependencies] +flake8 = "*" +isort = ">=5.0.0,<6" + +[package.extras] +test = ["pytest"] + +[[package]] +name = "flake8-quotes" +version = "3.3.2" +description = "Flake8 lint for quotes." +optional = false +python-versions = "*" +files = [ + {file = "flake8-quotes-3.3.2.tar.gz", hash = "sha256:6e26892b632dacba517bf27219c459a8396dcfac0f5e8204904c5a4ba9b480e1"}, +] + +[package.dependencies] +flake8 = "*" + +[[package]] +name = "flake8-rst-docstrings" +version = "0.3.0" +description = "Python docstring reStructuredText (RST) validator for flake8" +optional = false +python-versions = ">=3.7" +files = [ + {file = "flake8-rst-docstrings-0.3.0.tar.gz", hash = "sha256:d1ce22b4bd37b73cd86b8d980e946ef198cfcc18ed82fedb674ceaa2f8d1afa4"}, + {file = "flake8_rst_docstrings-0.3.0-py3-none-any.whl", hash = "sha256:f8c3c6892ff402292651c31983a38da082480ad3ba253743de52989bdc84ca1c"}, +] + +[package.dependencies] +flake8 = ">=3" +pygments = "*" +restructuredtext-lint = "*" + +[package.extras] +develop = ["build", "twine"] + +[[package]] +name = "flake8-string-format" +version = "0.3.0" +description = "string format checker, plugin for flake8" +optional = false +python-versions = "*" +files = [ + {file = "flake8-string-format-0.3.0.tar.gz", hash = "sha256:65f3da786a1461ef77fca3780b314edb2853c377f2e35069723348c8917deaa2"}, + {file = "flake8_string_format-0.3.0-py2.py3-none-any.whl", hash = "sha256:812ff431f10576a74c89be4e85b8e075a705be39bc40c4b4278b5b13e2afa9af"}, +] + +[package.dependencies] +flake8 = "*" + +[[package]] +name = "freezegun" +version = "1.2.2" +description = "Let your Python tests travel through time" +optional = false +python-versions = ">=3.6" +files = [ + {file = "freezegun-1.2.2-py3-none-any.whl", hash = "sha256:ea1b963b993cb9ea195adbd893a48d573fda951b0da64f60883d7e988b606c9f"}, + {file = "freezegun-1.2.2.tar.gz", hash = "sha256:cd22d1ba06941384410cd967d8a99d5ae2442f57dfafeff2fda5de8dc5c05446"}, +] + +[package.dependencies] +python-dateutil = ">=2.7" + +[[package]] +name = "gitdb" +version = "4.0.11" +description = "Git Object Database" +optional = false +python-versions = ">=3.7" +files = [ + {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, + {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, +] + +[package.dependencies] +smmap = ">=3.0.1,<6" + +[[package]] +name = "gitpython" +version = "3.1.40" +description = "GitPython is a Python library used to interact with Git repositories" +optional = false +python-versions = ">=3.7" +files = [ + {file = "GitPython-3.1.40-py3-none-any.whl", hash = "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a"}, + {file = "GitPython-3.1.40.tar.gz", hash = "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4"}, +] + +[package.dependencies] +gitdb = ">=4.0.1,<5" + +[package.extras] +test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-instafail", "pytest-subtests", "pytest-sugar"] + +[[package]] +name = "idna" +version = "3.4" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] + +[[package]] +name = "importlib-metadata" +version = "6.8.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, + {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isort" +version = "5.12.0" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, +] + +[package.extras] +colors = ["colorama (>=0.4.3)"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "mypy" +version = "1.5.1" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f33592ddf9655a4894aef22d134de7393e95fcbdc2d15c1ab65828eee5c66c70"}, + {file = "mypy-1.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:258b22210a4a258ccd077426c7a181d789d1121aca6db73a83f79372f5569ae0"}, + {file = "mypy-1.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9ec1f695f0c25986e6f7f8778e5ce61659063268836a38c951200c57479cc12"}, + {file = "mypy-1.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:abed92d9c8f08643c7d831300b739562b0a6c9fcb028d211134fc9ab20ccad5d"}, + {file = "mypy-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:a156e6390944c265eb56afa67c74c0636f10283429171018446b732f1a05af25"}, + {file = "mypy-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6ac9c21bfe7bc9f7f1b6fae441746e6a106e48fc9de530dea29e8cd37a2c0cc4"}, + {file = "mypy-1.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51cb1323064b1099e177098cb939eab2da42fea5d818d40113957ec954fc85f4"}, + {file = "mypy-1.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:596fae69f2bfcb7305808c75c00f81fe2829b6236eadda536f00610ac5ec2243"}, + {file = "mypy-1.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:32cb59609b0534f0bd67faebb6e022fe534bdb0e2ecab4290d683d248be1b275"}, + {file = "mypy-1.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:159aa9acb16086b79bbb0016145034a1a05360626046a929f84579ce1666b315"}, + {file = "mypy-1.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f6b0e77db9ff4fda74de7df13f30016a0a663928d669c9f2c057048ba44f09bb"}, + {file = "mypy-1.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:26f71b535dfc158a71264e6dc805a9f8d2e60b67215ca0bfa26e2e1aa4d4d373"}, + {file = "mypy-1.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc3a600f749b1008cc75e02b6fb3d4db8dbcca2d733030fe7a3b3502902f161"}, + {file = "mypy-1.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:26fb32e4d4afa205b24bf645eddfbb36a1e17e995c5c99d6d00edb24b693406a"}, + {file = "mypy-1.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:82cb6193de9bbb3844bab4c7cf80e6227d5225cc7625b068a06d005d861ad5f1"}, + {file = "mypy-1.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4a465ea2ca12804d5b34bb056be3a29dc47aea5973b892d0417c6a10a40b2d65"}, + {file = "mypy-1.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9fece120dbb041771a63eb95e4896791386fe287fefb2837258925b8326d6160"}, + {file = "mypy-1.5.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d28ddc3e3dfeab553e743e532fb95b4e6afad51d4706dd22f28e1e5e664828d2"}, + {file = "mypy-1.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:57b10c56016adce71fba6bc6e9fd45d8083f74361f629390c556738565af8eeb"}, + {file = "mypy-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:ff0cedc84184115202475bbb46dd99f8dcb87fe24d5d0ddfc0fe6b8575c88d2f"}, + {file = "mypy-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8f772942d372c8cbac575be99f9cc9d9fb3bd95c8bc2de6c01411e2c84ebca8a"}, + {file = "mypy-1.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5d627124700b92b6bbaa99f27cbe615c8ea7b3402960f6372ea7d65faf376c14"}, + {file = "mypy-1.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:361da43c4f5a96173220eb53340ace68cda81845cd88218f8862dfb0adc8cddb"}, + {file = "mypy-1.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:330857f9507c24de5c5724235e66858f8364a0693894342485e543f5b07c8693"}, + {file = "mypy-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:c543214ffdd422623e9fedd0869166c2f16affe4ba37463975043ef7d2ea8770"}, + {file = "mypy-1.5.1-py3-none-any.whl", hash = "sha256:f757063a83970d67c444f6e01d9550a7402322af3557ce7630d3c957386fa8f5"}, + {file = "mypy-1.5.1.tar.gz", hash = "sha256:b031b9601f1060bf1281feab89697324726ba0c0bae9d7cd7ab4b690940f0b92"}, +] + +[package.dependencies] +mypy-extensions = ">=1.0.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = ">=4.1.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "pbr" +version = "5.11.1" +description = "Python Build Reasonableness" +optional = false +python-versions = ">=2.6" +files = [ + {file = "pbr-5.11.1-py2.py3-none-any.whl", hash = "sha256:567f09558bae2b3ab53cb3c1e2e33e726ff3338e7bae3db5dc954b3a44eef12b"}, + {file = "pbr-5.11.1.tar.gz", hash = "sha256:aefc51675b0b533d56bb5fd1c8c6c0522fe31896679882e1c4c63d5e4a0fccb3"}, +] + +[[package]] +name = "pep8-naming" +version = "0.13.3" +description = "Check PEP-8 naming conventions, plugin for flake8" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pep8-naming-0.13.3.tar.gz", hash = "sha256:1705f046dfcd851378aac3be1cd1551c7c1e5ff363bacad707d43007877fa971"}, + {file = "pep8_naming-0.13.3-py3-none-any.whl", hash = "sha256:1a86b8c71a03337c97181917e2b472f0f5e4ccb06844a0d6f0a33522549e7a80"}, +] + +[package.dependencies] +flake8 = ">=5.0.0" + +[[package]] +name = "pluggy" +version = "1.3.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "pycodestyle" +version = "2.11.1" +description = "Python style guide checker" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, + {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, +] + +[[package]] +name = "pydocstyle" +version = "6.3.0" +description = "Python docstring style checker" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, + {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, +] + +[package.dependencies] +snowballstemmer = ">=2.2.0" + +[package.extras] +toml = ["tomli (>=1.2.3)"] + +[[package]] +name = "pyflakes" +version = "3.1.0" +description = "passive checker of Python programs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, + {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, +] + +[[package]] +name = "pygments" +version = "2.16.1" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, + {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, +] + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "pytest" +version = "7.4.2" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"}, + {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "4.1.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, + {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + +[[package]] +name = "pytest-freezer" +version = "0.4.8" +description = "Pytest plugin providing a fixture interface for spulec/freezegun" +optional = false +python-versions = ">= 3.6" +files = [ + {file = "pytest_freezer-0.4.8-py3-none-any.whl", hash = "sha256:644ce7ddb8ba52b92a1df0a80a699bad2b93514c55cf92e9f2517b68ebe74814"}, + {file = "pytest_freezer-0.4.8.tar.gz", hash = "sha256:8ee2f724b3ff3540523fa355958a22e6f4c1c819928b78a7a183ae4248ce6ee6"}, +] + +[package.dependencies] +freezegun = ">=1.0" +pytest = ">=3.6" + +[[package]] +name = "pytest-randomly" +version = "3.15.0" +description = "Pytest plugin to randomly order tests and control random.seed." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest_randomly-3.15.0-py3-none-any.whl", hash = "sha256:0516f4344b29f4e9cdae8bce31c4aeebf59d0b9ef05927c33354ff3859eeeca6"}, + {file = "pytest_randomly-3.15.0.tar.gz", hash = "sha256:b908529648667ba5e54723088edd6f82252f540cc340d748d1fa985539687047"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} +pytest = "*" + +[[package]] +name = "pytest-timeout" +version = "2.2.0" +description = "pytest plugin to abort hanging tests" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-timeout-2.2.0.tar.gz", hash = "sha256:3b0b95dabf3cb50bac9ef5ca912fa0cfc286526af17afc806824df20c2f72c90"}, + {file = "pytest_timeout-2.2.0-py3-none-any.whl", hash = "sha256:bde531e096466f49398a59f2dde76fa78429a09a12411466f88a07213e220de2"}, +] + +[package.dependencies] +pytest = ">=5.0.0" + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-mock" +version = "1.11.0" +description = "Mock out responses from the requests package" +optional = false +python-versions = "*" +files = [ + {file = "requests-mock-1.11.0.tar.gz", hash = "sha256:ef10b572b489a5f28e09b708697208c4a3b2b89ef80a9f01584340ea357ec3c4"}, + {file = "requests_mock-1.11.0-py2.py3-none-any.whl", hash = "sha256:f7fae383f228633f6bececebdab236c478ace2284d6292c6e7e2867b9ab74d15"}, +] + +[package.dependencies] +requests = ">=2.3,<3" +six = "*" + +[package.extras] +fixture = ["fixtures"] +test = ["fixtures", "mock", "purl", "pytest", "requests-futures", "sphinx", "testtools"] + +[[package]] +name = "restructuredtext-lint" +version = "1.4.0" +description = "reStructuredText linter" +optional = false +python-versions = "*" +files = [ + {file = "restructuredtext_lint-1.4.0.tar.gz", hash = "sha256:1b235c0c922341ab6c530390892eb9e92f90b9b75046063e047cacfb0f050c45"}, +] + +[package.dependencies] +docutils = ">=0.11,<1.0" + +[[package]] +name = "rich" +version = "13.6.0" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"}, + {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + +[[package]] +name = "setuptools" +version = "68.2.2" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, + {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "smmap" +version = "5.0.1" +description = "A pure Python implementation of a sliding window memory map manager" +optional = false +python-versions = ">=3.7" +files = [ + {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, + {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, +] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +optional = false +python-versions = "*" +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] + +[[package]] +name = "soupsieve" +version = "2.5" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.8" +files = [ + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, +] + +[[package]] +name = "stevedore" +version = "5.1.0" +description = "Manage dynamic plugins for Python applications" +optional = false +python-versions = ">=3.8" +files = [ + {file = "stevedore-5.1.0-py3-none-any.whl", hash = "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d"}, + {file = "stevedore-5.1.0.tar.gz", hash = "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c"}, +] + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "types-requests" +version = "2.31.0.2" +description = "Typing stubs for requests" +optional = false +python-versions = "*" +files = [ + {file = "types-requests-2.31.0.2.tar.gz", hash = "sha256:6aa3f7faf0ea52d728bb18c0a0d1522d9bfd8c72d26ff6f61bfc3d06a411cf40"}, + {file = "types_requests-2.31.0.2-py3-none-any.whl", hash = "sha256:56d181c85b5925cbc59f4489a57e72a8b2166f18273fd8ba7b6fe0c0b986f12a"}, +] + +[package.dependencies] +types-urllib3 = "*" + +[[package]] +name = "types-urllib3" +version = "1.26.25.14" +description = "Typing stubs for urllib3" +optional = false +python-versions = "*" +files = [ + {file = "types-urllib3-1.26.25.14.tar.gz", hash = "sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f"}, + {file = "types_urllib3-1.26.25.14-py3-none-any.whl", hash = "sha256:9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e"}, +] + +[[package]] +name = "typing-extensions" +version = "4.8.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, +] + +[[package]] +name = "urllib3" +version = "2.0.7" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.7" +files = [ + {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, + {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "wemake-python-styleguide" +version = "0.18.0" +description = "The strictest and most opinionated python linter ever" +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "wemake_python_styleguide-0.18.0-py3-none-any.whl", hash = "sha256:2219be145185edcd5e01f4ce49e3dea11acc34f2c377face0c175bb6ea6ac988"}, + {file = "wemake_python_styleguide-0.18.0.tar.gz", hash = "sha256:69139858cf5b2a9ba09dac136e2873a4685515768f68fdef2684ebefd7b1dafd"}, +] + +[package.dependencies] +astor = ">=0.8,<0.9" +attrs = "*" +darglint = ">=1.2,<2.0" +flake8 = ">5" +flake8-bandit = ">=4.1,<5.0" +flake8-broken-line = ">=1.0,<2.0" +flake8-bugbear = ">=23.5,<24.0" +flake8-commas = ">=2.0,<3.0" +flake8-comprehensions = ">=3.1,<4.0" +flake8-debugger = ">=4.0,<5.0" +flake8-docstrings = ">=1.3,<2.0" +flake8-eradicate = ">=1.5,<2.0" +flake8-isort = ">=6.0,<7.0" +flake8-quotes = ">=3.0,<4.0" +flake8-rst-docstrings = ">=0.3,<0.4" +flake8-string-format = ">=0.3,<0.4" +pep8-naming = ">=0.13,<0.14" +pygments = ">=2.4,<3.0" +setuptools = "*" +typing_extensions = ">=4.0,<5.0" + +[[package]] +name = "zipp" +version = "3.17.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.9" +content-hash = "b725c780b419b14540a1d4801f1849230d4e8a1b51a9381e36ff476eb8ab598c" diff --git a/Industrial_developed_hangman/pyproject.toml b/Industrial_developed_hangman/pyproject.toml new file mode 100644 index 00000000000..b70606ab82f --- /dev/null +++ b/Industrial_developed_hangman/pyproject.toml @@ -0,0 +1,35 @@ +[tool.poetry] +name = "Hangman" +version = "0.2.0" +description = "" +authors = ["DiodDan "] +readme = "README.md" +packages = [{include = "hangman", from = "src"}] + +[tool.poetry.dependencies] +python = "^3.9" +requests = "2.31.0" +colorama = "0.4.6" +beautifulsoup4 = "4.12" + + +[tool.poetry.group.dev.dependencies] +mypy = "1.5.1" +wemake-python-styleguide = "0.18.0" +isort = "5.12.0" +pytest = "7.4.2" +pytest-cov = "4.1.0" +pytest-timeout = "2.2.0" +pytest-randomly = "3.15.0" +requests-mock = "1.11.0" +pytest-freezer = "0.4.8" +types-requests = " 2.31.0.2" + +[build-system] +requires = ["poetry-core", "colorama", "bs4", "requests"] +build-backend = "poetry.core.masonry.api" + +[tool.isort] +line_length = 80 +multi_line_output = 3 +include_trailing_comma = true diff --git a/Industrial_developed_hangman/pytest.ini b/Industrial_developed_hangman/pytest.ini new file mode 100644 index 00000000000..f51da414608 --- /dev/null +++ b/Industrial_developed_hangman/pytest.ini @@ -0,0 +1,5 @@ +[pytest] +markers = + internet_required: marks tests that requires internet connection (deselect with '-m "not internet_required"') + serial +timeout = 20 diff --git a/Industrial_developed_hangman/setup.cfg b/Industrial_developed_hangman/setup.cfg new file mode 100644 index 00000000000..f57029a0492 --- /dev/null +++ b/Industrial_developed_hangman/setup.cfg @@ -0,0 +1,48 @@ +[flake8] +max-line-length = 120 +docstring_style = sphinx +max-arguments = 6 +exps-for-one-empty-line = 0 +ignore = + D100, + D104, + +per-file-ignores = + tests/*: + # Missing docstring in public class + D101, + # Missing docstring in public method + D102, + # Missing docstring in public function + D103, + # Missing docstring in magic method + D105, + # Missing docstring in __init__ + D107, + # Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. + S101, + # Found magic number + WPS432, + # Found wrong keyword: pass + WPS420, + # Found incorrect node inside `class` body + WPS604, + # Found outer scope names shadowing: message_update + WPS442, + # Found comparison with float or complex number + WPS459, + # split between test action and assert + WPS473, + # Found compare with falsy constant + WPS520, + # Found string literal over-use + WPS226 + # Found overused expression + WPS204 + # Found too many module members + WPS202 + +[mypy] +ignore_missing_imports = True +check_untyped_defs = True +disallow_untyped_calls = True diff --git a/Industrial_developed_hangman/src/hangman/__init__.py b/Industrial_developed_hangman/src/hangman/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Industrial_developed_hangman/src/hangman/main.py b/Industrial_developed_hangman/src/hangman/main.py new file mode 100644 index 00000000000..bad2a4470d0 --- /dev/null +++ b/Industrial_developed_hangman/src/hangman/main.py @@ -0,0 +1,170 @@ +import random +import time +from enum import Enum +from pathlib import Path +from typing import Callable, List + +import requests +from bs4 import BeautifulSoup +from colorama import Fore, Style + +DEBUG = False +success_code = 200 +request_timeout = 1000 +data_path = Path(__file__).parent.parent.parent / 'Data' +year = 4800566455 + + +class Source(Enum): + """Enum that represents switch between local and web word parsing.""" + + FROM_FILE = 0 # noqa: WPS115 + FROM_INTERNET = 1 # noqa: WPS115 + + +def print_wrong(text: str, print_function: Callable[[str], None]) -> None: + """ + Print styled text(red). + + :parameter text: text to print. + :parameter print_function: Function that will be used to print in game. + """ + text_to_print = Style.RESET_ALL + Fore.RED + text + print_function(text_to_print) + + +def print_right(text: str, print_function: Callable[[str], None]) -> None: + """ + Print styled text(red). + + :parameter text: text to print. + :parameter print_function: Function that will be used to print in game. + """ + print_function(Style.RESET_ALL + Fore.GREEN + text) + + +def parse_word_from_local(choice_function: Callable[[List[str]], str] = random.choice) -> str: + # noqa: DAR201 + """ + Parse word from local file. + + :parameter choice_function: Function that will be used to choice a word from file. + :returns str: string that contains the word. + :raises FileNotFoundError: file to read words not found. + """ + try: + with open(data_path / 'local_words.txt', encoding='utf8') as words_file: + return choice_function(words_file.read().split('\n')) + except FileNotFoundError: + raise FileNotFoundError('File local_words.txt was not found') + + +def parse_word_from_site(url: str = 'https://randomword.com') -> str: + # noqa: DAR201 + """ + Parse word from website. + + :param url: url that word will be parsed from. + :return Optional[str]: string that contains the word. + :raises ConnectionError: no connection to the internet. + :raises RuntimeError: something go wrong with getting the word from site. + """ + try: + page: requests.Response = requests.get(url, timeout=request_timeout) + except ConnectionError: + raise ConnectionError('There is no connection to the internet') + if page.status_code == success_code: + soup = BeautifulSoup(page.text, 'html.parser') + return soup.find('div', id='random_word').text + raise RuntimeError('Something go wrong with getting the word from site') + + +class MainProcess(object): + """Manages game process.""" + + def __init__(self, source: Enum, pr_func: Callable, in_func: Callable, ch_func: Callable) -> None: + """ + Init MainProcess object. + + :parameter in_func: Function that will be used to get input in game. + :parameter source: Represents source to get word. + :parameter pr_func: Function that will be used to print in game. + :parameter ch_func: Function that will be used to choice word. + """ + self._source = source + self._answer_word = '' + self._word_string_to_show = '' + self._guess_attempts_coefficient = 2 + self._print_function = pr_func + self._input_function = in_func + self._choice_function = ch_func + + def get_word(self) -> str: + # noqa: DAR201 + """ + Parse word(wrapper for local and web parse). + + :returns str: string that contains the word. + :raises AttributeError: Not existing enum + """ + if self._source == Source.FROM_INTERNET: + return parse_word_from_site() + elif self._source == Source.FROM_FILE: + return parse_word_from_local(self._choice_function) + raise AttributeError('Non existing enum') + + def user_lose(self) -> None: + """Print text for end of game and exits.""" + print_wrong(f"YOU LOST(the word was '{self._answer_word}')", self._print_function) # noqa:WPS305 + + def user_win(self) -> None: + """Print text for end of game and exits.""" + print_wrong(f'{self._word_string_to_show} YOU WON', self._print_function) # noqa:WPS305 + + def game_process(self, user_character: str) -> bool: + # noqa: DAR201 + """ + Process user input. + + :parameter user_character: User character. + :returns bool: state of game. + """ + if user_character in self._answer_word: + word_list_to_show = list(self._word_string_to_show) + for index, character in enumerate(self._answer_word): + if character == user_character: + word_list_to_show[index] = user_character + self._word_string_to_show = ''.join(word_list_to_show) + else: + print_wrong('There is no such character in word', self._print_function) + if self._answer_word == self._word_string_to_show: + self.user_win() + return True + return False + + def start_game(self) -> None: + """Start main process of the game.""" + if time.time() > year: + print_right('this program is more then 100years age', self._print_function) + with open(data_path / 'text_images.txt', encoding='utf8') as text_images_file: + print_wrong(text_images_file.read(), self._print_function) + print_wrong('Start guessing...', self._print_function) + self._answer_word = self.get_word() + self._word_string_to_show = '_' * len(self._answer_word) + attempts_amount = int(self._guess_attempts_coefficient * len(self._answer_word)) + if DEBUG: + print_right(self._answer_word, self._print_function) + for attempts in range(attempts_amount): + user_remaining_attempts = attempts_amount - attempts + print_right(f'You have {user_remaining_attempts} more attempts', self._print_function) # noqa:WPS305 + print_right(f'{self._word_string_to_show} enter character to guess: ', self._print_function) # noqa:WPS305 + user_character = self._input_function().lower() + if self.game_process(user_character): + break + if '_' in self._word_string_to_show: + self.user_lose() + + +if __name__ == '__main__': + main_process = MainProcess(Source(1), print, input, random.choice) + main_process.start_game() From 1c04b3a094eb4cd4f7b67bbdab6e2f382d132762 Mon Sep 17 00:00:00 2001 From: DIOD Date: Wed, 1 Nov 2023 18:53:30 +0100 Subject: [PATCH 41/44] Image Added into Industrial_developed_hangman readme --- .../Data/local_words.txt | 200 ++++++++++++++++++ .../Data/text_images.txt | 16 ++ Industrial_developed_hangman/README.md | 5 + Industrial_developed_hangman/recorces/img.png | Bin 0 -> 42763 bytes .../tests/__init__.py | 0 .../tests/test_hangman/__init__.py | 0 .../tests/test_hangman/test_main.py | 105 +++++++++ 7 files changed, 326 insertions(+) create mode 100644 Industrial_developed_hangman/Data/local_words.txt create mode 100644 Industrial_developed_hangman/Data/text_images.txt create mode 100644 Industrial_developed_hangman/recorces/img.png create mode 100644 Industrial_developed_hangman/tests/__init__.py create mode 100644 Industrial_developed_hangman/tests/test_hangman/__init__.py create mode 100644 Industrial_developed_hangman/tests/test_hangman/test_main.py diff --git a/Industrial_developed_hangman/Data/local_words.txt b/Industrial_developed_hangman/Data/local_words.txt new file mode 100644 index 00000000000..ba958fe23e4 --- /dev/null +++ b/Industrial_developed_hangman/Data/local_words.txt @@ -0,0 +1,200 @@ +jam +veteran +environmental +sound +make +first-hand +disposition +handy +dance +expression +take +professor +swipe +publisher +tube +thread +paradox +bold +feeling +seal +medicine +ancestor +designer +sustain +define +stomach +minister +coffee +disorder +cow +clash +sector +discount +anger +nationalist +cater +mole +speculate +far +retirement +rub +sample +contribution +distance +palace +holiday +native +debut +steak +tired +pump +mayor +develop +cool +economics +prospect +regular +suntan +husband +praise +rule +soprano +secular +interactive +barrel +permanent +childish +ministry +rank +ball +difficult +linger +comfortable +education +grief +check +user +fish +catch +aquarium +photograph +aisle +justice +preoccupation +liberal +diagram +disturbance +separation +concentration +tidy +appointment +fling +exception +gutter +nature +relieve +illustrate +bathtub +cord +bus +divorce +country +mountain +slump +acquit +inn +achieve +bloodshed +bundle +spell +petty +closed +mud +begin +robot +chorus +prison +lend +bomb +exploration +wrist +fist +agency +example +factory +disagreement +assault +absolute +consider +sign +raw +flood +definition +implication +judge +extraterrestrial +corn +breakfast +shelter +buffet +seize +credit +hardship +growth +velvet +application +cheese +secretion +loop +smile +withdrawal +execute +daughter +quota +deny +defeat +knee +brain +packet +ignorance +core +stumble +glide +reign +huge +position +alive +we +gate +replacement +mourning +incapable +reach +rehearsal +profile +fax +sit +compete +smart +gradient +tough +house +pocket +spider +ditch +critical +ignorant +policy +experience +exhibition +forum +contribution +wrestle +cave +bet +stool +store +formal +basketball +journal diff --git a/Industrial_developed_hangman/Data/text_images.txt b/Industrial_developed_hangman/Data/text_images.txt new file mode 100644 index 00000000000..06338355b18 --- /dev/null +++ b/Industrial_developed_hangman/Data/text_images.txt @@ -0,0 +1,16 @@ +╔══╗─╔╗╔╗╔══╗╔═══╗─╔══╗╔╗╔╗╔╗╔╗╔══╗ +║╔╗║─║║║║║╔═╝║╔══╝─║╔╗║║║║║║║║║║╔╗║ +║╚╝╚╗║║║║║║──║╚══╗─║║║║║║║║║║║║║╚╝║ +║╔═╗║║║╔║║║──║╔══╝─║║║║║║╔║║║║║║╔╗║ +║╚═╝║║╚╝║║╚═╗║╚══╗╔╝║║║║╚╝║║╚╝║║║║║ +╚═══╝╚══╝╚══╝╚═══╝╚═╝╚╝╚══╝╚══╗╚╝╚╝ + ⡖⠒⢒⣶⠖⠒⠒⠒⡖⠒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ + ⡇⣠⠟⠁⠀⠀⠀⡖⠓⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ + ⡿⠉⠀⠀⠀⠀⠀⢹⣞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ + ⡇⠀⠀⠀⠀⠀⣠⠻⡟⢧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀ ⡇⠀⠀⠀⠀⠐⠃⢨⡧⠀⠳⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀ ⡇⠀⠀⠀⠀⠀⠀⠠⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀ ⡇⠀⠀⠀⠀⠀⠀⢨⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀ ⡇⠀⠀⠀⠀⠀⠀⠆⠘⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀ ⡇⠀⠀⠀⠀⠀⠈⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀ ⠧⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤ diff --git a/Industrial_developed_hangman/README.md b/Industrial_developed_hangman/README.md index 60147752200..71fb5bd5724 100644 --- a/Industrial_developed_hangman/README.md +++ b/Industrial_developed_hangman/README.md @@ -4,4 +4,9 @@ to install dependencies got to repository "Industrial_developed_hangman" by `cd to start it use `make build` command +example of programm run: + + +![img.png](recorces/img.png) + also makefile have lint command to lint source code \ No newline at end of file diff --git a/Industrial_developed_hangman/recorces/img.png b/Industrial_developed_hangman/recorces/img.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9930e1d230194900cf7c7b1aaf7edd25866963 GIT binary patch literal 42763 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 None: + self.container: List[str] = [] + + def __call__(self, value_to_print: str) -> None: + self.container.append(str(value_to_print)) + + +class FkInput(object): + def __init__(self, values_to_input: List[str]) -> None: + self.values_to_input: List[str] = values_to_input + + def __call__(self) -> str: + return self.values_to_input.pop(0) + + +@pytest.fixture +def choice_fn() -> Callable: + return lambda array: array[0] # noqa: E731 + + +def test_parse_word_from_local() -> None: + assert isinstance(parse_word_from_local(), str) + + +def test_parse_word_from_local_error() -> None: + data_path = Path(os.path.abspath('')) / 'Data' + real_name = 'local_words.txt' + time_name = 'local_words_not_exist.txt' + + os.rename(data_path / real_name, data_path / time_name) + with pytest.raises(FileNotFoundError): + parse_word_from_local() + os.rename(data_path / time_name, data_path / real_name) + + +@pytest.mark.internet_required +def test_parse_word_from_site() -> None: + assert isinstance(parse_word_from_site(), str) + + +def test_parse_word_from_site_no_internet() -> None: + with requests_mock.Mocker() as mock: + mock.get('https://randomword.com', text='
some text
') + assert parse_word_from_site() == 'some text' + + +def test_parse_word_from_site_err() -> None: + with pytest.raises(RuntimeError): + parse_word_from_site(url='https://www.google.com/dsfsdfds/sdfsdf/sdfds') + + +def test_get_word(choice_fn: Callable) -> None: + fk_print = FkPrint() + fk_input = FkInput(['none']) + main_process = MainProcess(Source(1), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn) + + assert isinstance(main_process.get_word(), str) + + +def test_start_game_win(choice_fn: Callable) -> None: + fk_print = FkPrint() + fk_input = FkInput(['j', 'a', 'm']) + main_process = MainProcess(Source(0), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn) + + main_process.start_game() + + assert 'YOU WON' in fk_print.container[-1] + + +@pytest.mark.parametrize('input_str', [[letter] * 10 for letter in 'qwertyuiopasdfghjklzxcvbnm']) # noqa: WPS435 +def test_start_game_loose(input_str: List[str], choice_fn: Callable) -> None: + fk_print = FkPrint() + fk_input = FkInput(input_str) + main_process = MainProcess(Source(0), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn) + + main_process.start_game() + + assert 'YOU LOST' in fk_print.container[-1] + + +def test_wow_year(freezer, choice_fn: Callable) -> None: + freezer.move_to('2135-10-17') + fk_print = FkPrint() + fk_input = FkInput(['none'] * 100) # noqa: WPS435 + main_process = MainProcess(Source(0), pr_func=fk_print, in_func=fk_input, ch_func=choice_fn) + + main_process.start_game() + + assert 'this program' in fk_print.container[0] From c5997d4a4e2960b4d5f4c85534b7169c6cd50ddd Mon Sep 17 00:00:00 2001 From: DIOD Date: Fri, 3 Nov 2023 02:19:36 +0100 Subject: [PATCH 42/44] Industrial_developed_hangman changed to api usage --- Industrial_developed_hangman/src/hangman/main.py | 11 +++++------ .../tests/test_hangman/test_main.py | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Industrial_developed_hangman/src/hangman/main.py b/Industrial_developed_hangman/src/hangman/main.py index bad2a4470d0..b2a7e780ac3 100644 --- a/Industrial_developed_hangman/src/hangman/main.py +++ b/Industrial_developed_hangman/src/hangman/main.py @@ -1,3 +1,4 @@ +import json import random import time from enum import Enum @@ -5,7 +6,6 @@ from typing import Callable, List import requests -from bs4 import BeautifulSoup from colorama import Fore, Style DEBUG = False @@ -59,7 +59,7 @@ def parse_word_from_local(choice_function: Callable[[List[str]], str] = random.c raise FileNotFoundError('File local_words.txt was not found') -def parse_word_from_site(url: str = 'https://randomword.com') -> str: +def parse_word_from_site(url: str = 'https://random-word-api.herokuapp.com/word') -> str: # noqa: DAR201 """ Parse word from website. @@ -70,12 +70,11 @@ def parse_word_from_site(url: str = 'https://randomword.com') -> str: :raises RuntimeError: something go wrong with getting the word from site. """ try: - page: requests.Response = requests.get(url, timeout=request_timeout) + response: requests.Response = requests.get(url, timeout=request_timeout) except ConnectionError: raise ConnectionError('There is no connection to the internet') - if page.status_code == success_code: - soup = BeautifulSoup(page.text, 'html.parser') - return soup.find('div', id='random_word').text + if response.status_code == success_code: + return json.loads(response.content.decode())[0] raise RuntimeError('Something go wrong with getting the word from site') diff --git a/Industrial_developed_hangman/tests/test_hangman/test_main.py b/Industrial_developed_hangman/tests/test_hangman/test_main.py index 052c1960aab..46d0b1d6f0e 100644 --- a/Industrial_developed_hangman/tests/test_hangman/test_main.py +++ b/Industrial_developed_hangman/tests/test_hangman/test_main.py @@ -56,7 +56,7 @@ def test_parse_word_from_site() -> None: def test_parse_word_from_site_no_internet() -> None: with requests_mock.Mocker() as mock: - mock.get('https://randomword.com', text='
some text
') + mock.get('https://random-word-api.herokuapp.com/word', text='["some text"]') assert parse_word_from_site() == 'some text' From a344c4a424757e8fef9e0718962ffd3d13c3efda Mon Sep 17 00:00:00 2001 From: anuragdaksh7 Date: Mon, 6 Nov 2023 12:48:07 +0530 Subject: [PATCH 43/44] added ping pong --- PingPong/Ball.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ PingPong/Slab.py | 31 ++++++++++++++++++++++++++ PingPong/main.py | 40 +++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 PingPong/Ball.py create mode 100644 PingPong/Slab.py create mode 100644 PingPong/main.py diff --git a/PingPong/Ball.py b/PingPong/Ball.py new file mode 100644 index 00000000000..ec1a4a6768f --- /dev/null +++ b/PingPong/Ball.py @@ -0,0 +1,58 @@ +import pygame +pygame.init() + +class Ball: + + def __init__(self, pos, vel, win, rad, minCoord, maxCoord): + + self.pos = pos + self.vel = vel + self.win = win + self.rad = rad + self.minCoord = minCoord + self.maxCoord = maxCoord + + + def drawBall(self): + + pygame.draw.circle(self.win, (255,)*3, self.pos, self.rad, 0) + + + def doHorizontalFlip(self): + + self.vel[0] *= -1 + + + def doVerticalFlip(self): + + self.vel[1] *= -1 + + + def borderCollisionCheck(self): + + if (self.pos[0] <= self.minCoord[0]) or (self.pos[0] >= self.maxCoord[0]): + + self.doHorizontalFlip() + + if (self.pos[1] <= self.minCoord[1]) or (self.pos[1] >= self.maxCoord[1]): + + self.doVerticalFlip() + + + def updatePos(self): + + self.pos = [self.pos[0]+self.vel[0], self.pos[1]+self.vel[1]] + + + def checkSlabCollision(self, slabPos): # slab pos = [xmin, ymin, xmax, ymax] + if ( + self.pos[0] + self.rad > slabPos[0] + and self.pos[0] - self.rad < slabPos[2] + and self.pos[1] + self.rad > slabPos[1] + and self.pos[1] - self.rad < slabPos[3] + ): + # Handle collision here (e.g., reverse ball's direction) + if self.pos[0] < slabPos[0] or self.pos[0] > slabPos[2]: + self.vel[0] *= -1 + if self.pos[1] < slabPos[1] or self.pos[1] > slabPos[3]: + self.vel[1] *= -1 \ No newline at end of file diff --git a/PingPong/Slab.py b/PingPong/Slab.py new file mode 100644 index 00000000000..c5fb5d70bec --- /dev/null +++ b/PingPong/Slab.py @@ -0,0 +1,31 @@ +import pygame +pygame.init() + +class Slab: + def __init__(self, win, size, pos, player, minPos, maxPos): + self.win = win + self.size = size + self.pos = pos + self.player = player #player = 1 or 2 + self.minPos = minPos + self.maxPos = maxPos + + + def draw(self): + pygame.draw.rect(self.win, (255, 255, 255), (self.pos[0], self.pos[1], self.size[0], self.size[1])) + + def getCoords(self): + return [self.pos[0], self.pos[1], self.pos[0] + self.size[0], self.pos[1] + self.size[1]] + + def updatePos(self): + keys = pygame.key.get_pressed() + if self.player == 1: + if keys[pygame.K_UP] and self.getCoords()[1]> self.minPos[1]: + self.pos[1] -= 0.3 + if keys[pygame.K_DOWN] and self.getCoords()[3]< self.maxPos[1]: + self.pos[1] += 0.3 + else: + if keys[pygame.K_w] and self.getCoords()[1]> self.minPos[1]: + self.pos[1] -= 0.3 + if keys[pygame.K_s] and self.getCoords()[3]< self.maxPos[1]: + self.pos[1] += 0.3 \ No newline at end of file diff --git a/PingPong/main.py b/PingPong/main.py new file mode 100644 index 00000000000..2892f8c9305 --- /dev/null +++ b/PingPong/main.py @@ -0,0 +1,40 @@ +from Ball import Ball +from Slab import Slab +import pygame + +WIDTH = 600 +HEIGHT = 600 +BLACK = (0,0,0) +WHITE = (255,)*3 +pygame.init() + +win = pygame.display.set_mode((WIDTH, HEIGHT )) + +print("Controls: W&S for player 1 and arrow up and down for player 2") + +ball = Ball([300,300 ], [0.3,0.1], win, 10, (0,0), (600,600)) +slab = Slab(win, [10,100], [500, 300], 1, (0, 0), (600, 600)) +slab2 = Slab(win, [10,100], [100, 300], 2, (0, 0), (600, 600)) +run = True +while run: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + run = False + + keys = pygame.key.get_pressed() + win.fill(BLACK) + + ball.borderCollisionCheck() + ball.checkSlabCollision(slab.getCoords()) + ball.checkSlabCollision(slab2.getCoords()) + ball.updatePos() + ball.drawBall() + + slab.updatePos() + slab.draw() + + slab2.updatePos() + slab2.draw() + + pygame.display.update() +pygame.quit() \ No newline at end of file From f3f2f20d3008118c25806fec4f3fd0361e958065 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 18:39:41 +0000 Subject: [PATCH 44/44] Bump pyglet from 2.0.9 to 2.0.10 Bumps [pyglet](https://github.com/pyglet/pyglet) from 2.0.9 to 2.0.10. - [Release notes](https://github.com/pyglet/pyglet/releases) - [Changelog](https://github.com/pyglet/pyglet/blob/master/RELEASE_NOTES) - [Commits](https://github.com/pyglet/pyglet/compare/v2.0.9...v2.0.10) --- updated-dependencies: - dependency-name: pyglet dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- PongPong_Game/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PongPong_Game/requirements.txt b/PongPong_Game/requirements.txt index 0facfc2ea8f..555f25f9c27 100644 --- a/PongPong_Game/requirements.txt +++ b/PongPong_Game/requirements.txt @@ -1 +1 @@ -pyglet==2.0.9 +pyglet==2.0.10