eshangj/stackoverflow_q_and_a_sample huggingface dataset:
Question: Python interpreter gives the following when generating an ISO-8601 formatted date/time string: >>> import datetime >>> datetime.datetime.now().isoformat(timespec='seconds') '2023-10-12T22:35:02'  Note that the '-' character in the string is a hypen-minus character. When going backwards to produce the datetime object, we do the following: >>> datetime.datetime.strptime('2023-10-12T22:35:02', '%Y-%m-%dT%H:%M:%S') datetime.datetime(2023, 10, 12, 22, 35, 2)  This all checks out. However, sometimes when the ISO-8601 formatted date/time string is provided from an external source, such as a parameter sent over in a GET/POST request, or in a .csv file, the hyphens are sent as the ‐ (U+2010) character, which causes the parsing to break: >>> datetime.datetime.strptime('2023‐10‐12T22:35:02', '%Y-%m-%dT%H:%M:%S') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_strptime.py", line 568, in _strptime_datetime tt, fraction, gmtoff_fraction = _strptime(data_string, format) File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_strptime.py", line 349, in _strptime raise ValueError("time data %r does not match format %r" % ValueError: time data '2023‐10‐12T22:35:02' does not match format '%Y-%m-%dT%H:%M:%S'  What is the correct standard? Is it hypen-minus - U+002D as given by Python when converting via .isoformat(), or hypen ‐ U+2010? Would it be best practice to accept both?

Answer: The ISO 8601 standard is not publicly available for free. Perhaps someone who has a copy can post a more definitive answer. ISO has published a brief summary of the ISO 8601 standard. The summary consistently uses HYPHEN-MINUS (0x2D). (Thanks to Giacomo Catenazzi for pointing this out in a comment.) RFC 3339 is based on ISO 8601, and it consistently uses the HYPHEN-MINUS character (0x2D), not the Unicode HYPHEN character (0x2010). Note that using HYPHEN-MINUS, which is an ASCII character, avoids issues with differing character sets. Reference: https://datatracker.ietf.org/doc/html/rfc3339 If you create timestamps intended to be consistent with ISO 8601, you should definitely use HYPHEN-MINUS. If you receive timestamps that are supposedly intended to be ISO 8601, but they include HYPHEN (0x2010) characters, you can choose to accept them. Whether you should accept them depends on the requirements of your project. If possible, ask whoever is generating timestamps to use the correct HYPHEN-MINUS characters. Once you start accepting non-standard input, you might have to do an open-ended amount of work.
Question: Initially, I needed to draw flowers using stars with a random number of branches. So, I wrote this function: def star(nb_branches:int , size:int) : for i in range(int(nb_branches / 2)) : forward(size * 3) left(180 - (360 / nb_branches))  (the arguments of this function are random and are created in another function but that is not the problem) However, I realised that when the number of branches were odd, the star wasn't a perfect star. I think the loop and/or the angle are the source of this problem. Since, I tried different angles and possibilities but I didn't obtain yet the answer. Here is an example of what I got from this function with odd numbers 

Answer: I was thinking about the differentiation between the odd and even numbers when I realized that my initial code worked well with even numbers, but with the half of branches. So, I took your function for the odd numbered stars and I intentionally doubled the number of branches for the even numbered stars to achieve it. Finally, I added a last forward to close the star. Here is the function : def star(nb_branches:int , size:int) : if(nb_branches % 2 == 0) : nb_branches *= 2 for i in range(nb_branches) : forward(size * 3) left(180 - (360 / nb_branches)) forward(size * 3 / 2) else : for i in range(nb_branches) : forward(size * 3) left(180 - (180 / nb_branches)) forward(size * 3 / 2)  There are surely some improvements to be made, but it works !
Question: I'm trying to write optional Python bindings for a Rust library, using maturin and PyO3. The default layout created by maturin is my-project ├── Cargo.toml ├── python │ └── my_project │ ├── __init__.py │ └── bar.py ├── pyproject.toml ├── README.md └── src └── lib.rs  where all Rust code, including the #[pymodule] attributes go into src/lib.rs: use pyo3::prelude::*; /// Formats the sum of two numbers as string. #[pyfunction] fn sum_as_string(a: usize, b: usize) -> PyResult<String> { Ok((a + b).to_string()) } /// A Python module implemented in Rust. #[pymodule] fn rir_generator(_py: Python, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(sum_as_string, m)?)?; Ok(()) }  However, since I want to put all of this code behind a conditional feature, I am trying to put all of that wrapper code into src/python.rs and then import it into src/lib.rs using #[cfg(feature = "python")] pub mod python;  But building this fails with the warning  Warning: Couldn't find the symbol PyInit_my_project in the native library. Python will fail to import this module. If you're using pyo3, check that #[pymodule] uses my_project as module name  If I put the code back into src/lib.rs, the warning disappears. Is there a way to put PyO3 bindings into a submodule that is then conditionally imported using features?

Answer: You are almost there. You need to add following section to the Cargo.toml to remove the warning. [features] default = ["python"] python = []  Quoting from the documentation:  Features are defined in the [features] table in Cargo.toml. Each feature specifies an array of other features or optional dependencies that it enables.  By default, all features are disabled unless explicitly enabled. This will cause the native library to build without PyInit_<module_name> symbol, Hence the warning. This can be changed by specifying the default feature
Question: The Python extension for VS Code used to provide builtin support for tools like formatters and linters, including:  Linting: Pylint, Flake8, Mypy, Bandit, Pydocstyle, Pycodestyle, Prospector, Pylama Formatting: autopep8, Black, YAPF  What's happening to the builtin support for these tools in the Python extension? How can I get integrated support for these tools in VS Code going forward?

Answer: Basically, see https://github.com/microsoft/vscode-python/wiki/Migration-to-Python-Tools-Extensions. I'll try to summarize/quote.  As announced on April 2022, our team has been working towards breaking the tools support we offer in the Python extension for Visual Studio Code into separate extensions, with the intent of improving performance, stability and no longer requiring the tools to be installed in a Python environment – as they can be shipped alongside an extension. This also allows the extensions to be shipped separately from the Python one once a new version of their respective tool becomes available.  Those extensions include: ms-python.pylint, ms-python.flake8, ms-python.mypy-type-checker, ms-python.black-formatter, ms-python.autopep8, ms-python.isort, charliermarsh.ruff, matangover.mypy, eeyore.yapf. Prompts, commands, and context menu items already started getting removed in the 2018.18.0 release- Ex. Remove old linter and formatter prompts and commands #21979 and Remove sort imports from command palette and context menu #22058. Lots of removals are in the iteration plan for the October 2023 release. Official VS Code Python docs for linting and for formatting look to have been updated already- at least partially, which is nice. Settings related to linting and formatting features that are moving to their own extensions are accordingly being removed (here's the full list with migration instructions). That includes python.linting.enabled, python.formatting.provider, and a host of settings related to specific linters and formatters. Not all the linters and formatters that were supported before have extensions yet. If you want to create a linter or formatter tool extension yourself, the Python Tools Extension Template will probably help. Or, you can take a look at the list of alternatives for deprecated settings, which includes trying another extension that supports multiple linters (Ex. charliermarsh.ruff), disabling extension auto-update and sticking with an older version of the Python extension / other extension that supports the tool you want to use, or writing a task to run the tool in the integrated terminal (you can also write custom problem matching).
Question: I was looking out to extract consecutive rows with specified text repeated continuously for more than 5 times. ex:  A B C 10 john 1 12 paul 1 23 kishan 1 12 teja 1 12 zebo 1 324 vauh -1 3434 krish -1 232 poo -1 4535 zoo 1 4343 doo 1 342 foo -1 123 soo 1 121 koo -1 34 loo -1 343454 moo -1 565343 noo -1 2323234 voo -1 3434 coo 1 545 xoo 1 6565 zoo 1 232321 qoo 1 34454 woo 1 546556 eoo 1 65665 roo -1 5343 too -1 3232 yoo 1 1212 uoo 1 23355667 ioo 1 787878 joo -1  I am looking out for the below result where the column value 'c' has consecutive 1's repeated more than 4 times as different groups . Output: A B C group 10 john 1 1 12 paul 1 1 23 kishan 1 1 12 teja 1 1 12 zebo 1 1 3434 coo 1 2 545 xoo 1 2 6565 zoo 1 2 232321 qoo 1 2 34454 woo 1 2 546556 eoo 1 2 

Answer: Using masks and factorize: # identify 1s m = df['C'].eq(1) # group consecutive values g = m.ne(m.shift()).cumsum() # identify stretches of 5+ 1s m2 = m & df.groupby(g)['C'].transform('size').ge(5) out = (df.loc[m2] .assign(group=pd.factorize(g[m2])[0]+1) )  Output:  A B C group 0 10 john 1 1 1 12 paul 1 1 2 23 kishan 1 1 3 12 teja 1 1 4 12 zebo 1 1 17 3434 coo 1 2 18 545 xoo 1 2 19 6565 zoo 1 2 20 232321 qoo 1 2 21 34454 woo 1 2 22 546556 eoo 1 2
Question: I would like to create a summary row to show differ between last and first row. e.g. import pandas as pd data = [ ['A',1,5], ['B',2,4], ['C',3,3], ['D',4,2], ['E',5,1], ['F',6,0] ] df = pd.DataFrame(data,columns=['name','x','y']) print(df)  Output ddataframe should be: : name x y : 0 A 1 5 : 1 B 2 4 : 2 C 3 3 : 3 D 4 2 : 4 E 5 1 : 5 F 6 0 : 6 diff 5 -5  What's the best way to do that?

Answer: Subtract first row from last row and concat the diff along index axis c = ['x', 'y'] diff = df[c].iloc[-1] - df[c].iloc[0] diff['name'] = 'diff' pd.concat([df, diff.to_frame().T], ignore_index=True)    name x y 0 A 1 5 1 B 2 4 2 C 3 3 3 D 4 2 4 E 5 1 5 F 6 0 6 diff 5 -5
Question: I am trying to install python 3.12 on an M1 Apple Mac using mamba as follows ...  mamba install -c conda-forge python=3.12.0  It yields the following error message ... Looking for: ['python=3.12.0'] conda-forge/osx-arm64 Using cache conda-forge/noarch Using cache Could not solve for environment specs The following packages are incompatible ├─ mamba is installable with the potential options │ ├─ mamba [1.0.0|1.1.0|...|1.5.1] would require │ │ └─ python_abi 3.11.* *_cp311, which can be installed; │ ├─ mamba [0.10.0|0.11.1|...|1.5.1] would require │ │ └─ python_abi 3.8.* *_cp38, which can be installed; │ ├─ mamba [0.10.0|0.11.1|...|1.5.1] would require │ │ └─ python_abi 3.9.* *_cp39, which can be installed; │ └─ mamba [0.18.1|0.18.2|...|1.5.1] would require │ └─ python_abi 3.10.* *_cp310, which can be installed; └─ python 3.12.0** is not installable because there are no viable options ├─ python 3.12.0 would require │ └─ python_abi 3.12.* *_cp312, which conflicts with any installable versions previously reported; └─ python 3.12.0rc3 would require └─ _python_rc, which does not exist (perhaps a missing channel).  Any pointers on how to do this properly would be much appreciated.

Answer: Upgrading base environment Python to a version that hasn't finished migrating1 is a recipe for trouble. Generally, one does not need to upgrade base environment's Python unless the Python version goes EOL. If you would like to explore the new Python 3.12, then create a new environment: mamba create -n py312 -c conda-forge python=3.12   [1]: Migration is the process on Conda Forge by which packages get rebuilt to support new global versions, such as Python 3.12 or R 4.3. Conda Forge provides a dashboard to track the status of migrations, such as Python 3.12.
Question:  I am running fastqc and multiqc in ubuntu linux terminal. fastqc runs perfectly without any issues but multiqc fails to run, showing the message. No idea how to fix the missing 'imp' module. I tried to read and apply every solution found in the internet or google. I used the command 'conda install multiqc' to install multiqc in the existing conda environment. I tried to install it in a new conda environment. Still, its showing the same message.The python version currently running is 3.12.0 Could anyone help to fix the issue?

Answer: Python 3.12 is new and the consequences of the changes it introduces (like dropping the imp module) need to propagate to the community. Stay on Python 3.11 for now.
Question: Consider a dataframe which has a series price with gaps containing NaN: import numpy as np import pandas as pd df = pd.DataFrame({"price": [1, 2, 3, np.nan, np.nan, np.nan, np.nan, np.nan, 9, 10]}, index=pd.date_range("2023-01-01", periods=10))   price 2023-01-01 1.0 2023-01-02 2.0 2023-01-03 3.0 2023-01-04 NaN 2023-01-05 NaN 2023-01-06 NaN 2023-01-07 NaN 2023-01-08 NaN 2023-01-09 9.0 2023-01-10 10.0  My desired result is to fill this gap using the last known gradient prior to the gap, i.e.:  price 2023-01-01 1.0 2023-01-02 2.0 2023-01-03 3.0 2023-01-04 4.0 2023-01-05 5.0 2023-01-06 6.0 2023-01-07 7.0 2023-01-08 8.0 2023-01-09 9.0 2023-01-10 10.0  This is easy to achieve using iteration: gradients = (df["price"] - df["price"].shift(1)).ffill() price_values = df["price"].values for index, val in enumerate(price_values): last_price = price_values[index - 1] gradient = gradients.iloc[index] if pd.isna(val) and not pd.isna(last_price) and not pd.isna(gradient): df["price"].iat[index] = last_price + gradient   price 2023-01-01 1.0 2023-01-02 2.0 2023-01-03 3.0 2023-01-04 4.0 2023-01-05 5.0 2023-01-06 6.0 2023-01-07 7.0 2023-01-08 8.0 2023-01-09 9.0 2023-01-10 10.0  This works fine but is slow. This also feels like a common use case and I would be surprised if it was not built in to pandas, but I am unable to find it in documentation. Is there a better, vectorised way to do this?

Answer: Assuming you want to use the last diff as a step size to increment the NaNs, you could compute the diff, ffill it, then use that to fillna the original Series, finally compute a groupby.cumsum: m = df['price'].notna() df['gradient_fill'] = (df['price'].fillna(df['price'].diff().ffill()) .groupby(m.cumsum()).cumsum() )  Output: NB. I changed the input for clarity.  price gradient_fill 2023-01-01 1.0 1.0 2023-01-02 20.0 20.0 2023-01-03 30.0 30.0 2023-01-04 NaN 40.0 2023-01-05 NaN 50.0 2023-01-06 NaN 60.0 2023-01-07 NaN 70.0 2023-01-08 NaN 80.0 2023-01-09 9.0 9.0 2023-01-10 10.0 10.0  Intermediates:  price m diff ffill fillna group gradient_fill 2023-01-01 1.0 True NaN NaN 1.0 1 1.0 2023-01-02 20.0 True 19.0 19.0 20.0 2 20.0 2023-01-03 30.0 True 10.0 10.0 30.0 3 30.0 2023-01-04 NaN False NaN 10.0 10.0 3 40.0 2023-01-05 NaN False NaN 10.0 10.0 3 50.0 2023-01-06 NaN False NaN 10.0 10.0 3 60.0 2023-01-07 NaN False NaN 10.0 10.0 3 70.0 2023-01-08 NaN False NaN 10.0 10.0 3 80.0 2023-01-09 9.0 True NaN 10.0 9.0 4 9.0 2023-01-10 10.0 True 1.0 1.0 10.0 5 10.0  You could also form groups of non-NA/NA and interpolate with a spline for each one: m = df['price'].notna() group = (m & ~m.shift(fill_value=False)).cumsum() df['spline'] = (df.groupby(group)['price'] .transform(lambda s: s.interpolate(method='spline', order=1)) )  Output:  price spline 2023-01-01 1.0 1.000000 2023-01-02 20.0 20.000000 2023-01-03 30.0 30.000000 2023-01-04 NaN 42.828422 2023-01-05 NaN 54.949738 2023-01-06 NaN 67.071054 2023-01-07 NaN 79.192371 2023-01-08 NaN 91.313687 2023-01-09 9.0 9.000000 2023-01-10 10.0 10.000000  Graphical comparison of approaches:
Question: I need to replace einsum operation with standard numpy operations in the following code: import numpy as np a = np.random.rand(128, 16, 8, 32) b = np.random.rand(256, 8, 32) output = np.einsum('aijb,rjb->ira', a, b)  How would I do that?

Answer: One option would be to align to a similar shape and broadcast multiply, then sum and reorder the axes: output2 = (b[None, None]*a[:,:,None]).sum(axis=(-1, -2)).transpose((1, 2, 0)) # assert np.allclose(output, output2)  But this is much less efficient as it's producing a large intermediate (shape (128, 16, 256, 8, 32)): # np.einsum('aijb,rjb->ira', a, b) 68.9 ms ± 23.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) # (b[None, None]*a[:,:,None]).sum(axis=(-1, -2)).transpose((1, 2, 0)) 4.66 s ± 1.65 s per loop (mean ± std. dev. of 7 runs, 1 loop each)  Shapes: # b[None, None].shape #a i r j b (1, 1, 256, 8, 32) # a[:,:,None].shape # a i r j b (128, 16, 1, 8, 32)
Question: The Python grammar has this rule: assignment: | NAME ':' expression ['=' annotated_rhs ] # other options for rule omitted  while the expression rules permit a lambda definition (lambdef). That means this python syntax is valid: q: lambda p: p * 4 = 1  Is there a use case for permitting a lambda there, or is this just a quirk of a somewhat loose grammar? Similarly, this allows conditional types a: int if b > 3 else str = quux, which seems a bit more sane but still unexpected.

Answer: This is specified under the PEP-0526(Syntax for Variable Annotations). Python does not care about the annotation as long as “it evaluates without raising”. It's the duty of the type-checker to flag it as invalid annotation. Quoting from the PEP:  Other uses of annotations While Python with this PEP will not object to: alice: 'well done' = 'A+' bob: 'what a shame' = 'F-' since it will not care about the type annotation beyond “it evaluates without raising”, a type checker that encounters it will flag it, unless disabled with #type: ignore or @no_type_check. However, since Python won’t care what the “type” is, if the above snippet is at the global level or in a class, __annotations__ will include {'alice': 'well done', 'bob': 'what a shame'}. These stored annotations might be used for other purposes, but with this PEP we explicitly recommend type hinting as the preferred use of annotations.  For example, running your snippet with mypy will produce the following error: file.py:1: error: Invalid type comment or annotation [valid-type]
Question: I have two dataframes - df1 & df2. I need to search each value from a specific column in df1 on df2 and return 2 nearest values. data1 = np.array([(1, 150), (2, 250), (3, 350), (4, 590)]) df1 = pd.DataFrame(data1, columns=['n', 'day']) df1 n day 0 1 150 1 2 250 2 3 350 3 4 590  data2 = np.array([(120, 10.5), (180, 10.7), (350, 11.2), (620, 15.5)]) df2 = pd.DataFrame(data2, columns=['day', 'rate']) df2 day rate 0 120 10.5 1 180 10.7 2 350 11.2 3 620 15.5  I managed to find the values using this function: #to find 2 nearest values def find_rates(df, s, x, n=2): diff = (s - x).abs() return df.loc[diff.nsmallest(n).index].sort_index()  Exemple: find_rates(df2, df2.day, 150, n=2) day rate 0 120.0 10.5 1 180.0 10.7 find_rates(df2, df2.day, 350, n=2) day rate 1 180.0 10.7 2 350.0 11.2  What I expect from this is to iterative search each "day" value from df1 on df2 and store 2 nearest values on df1 new columns: data3 = np.array([(1, 150, 120, 180, 10.5, 10.7), (2, 250, 180, 350, 10.7, 11.2), (3, 350, 180, 350, 10.7, 11.2), (4, 590, 350, 620, 11.2, 15.5)]) want = pd.DataFrame(data3, columns=['n', 'day', 'day1', 'day2', 'rate1', 'rate2']) want n day day1 day2 rate1 rate2 0 1.0 150.0 120.0 180.0 10.5 10.7 1 2.0 250.0 180.0 350.0 10.7 11.2 2 3.0 350.0 180.0 350.0 10.7 11.2 3 4.0 590.0 350.0 620.0 11.2 15.5  Any clues on how to do that?

Answer: Another possible solution : N = 2 day1 = df1["day"].to_numpy()[:, None] day2 = df2["day"].to_numpy(); arr2 = df2.to_numpy() idx = np.sort(np.argsort(np.abs(day2 - day1), axis=1)[:, :N]) days = pd.DataFrame(arr2[:, 0][idx], columns=["day1", "day2"]) rates = pd.DataFrame(arr2[:, 1][idx], columns=["rate1", "rate2"]) out = pd.concat([df1, days, rates], axis=1)  Output : print(out) n day day1 day2 rate1 rate2 0 1 150 120.00 180.00 10.50 10.70 1 2 250 180.00 350.00 10.70 11.20 2 3 350 180.00 350.00 10.70 11.20 3 4 590 350.00 620.00 11.20 15.50
Question: I recently encountered numpy.savez and numpy.savez_compressed. Both seem to work well with arrays of differing types, including object arrays. However, numpy.load does not work well with object type arrays. For example: import numpy as np numbers = np.full((10, 1), np.pi) strings = np.full((10, 1), "letters", dtype=object) np.savez("test.npz", numbers=numbers, strings=strings) data = np.load("test.npz")  Calling data["strings"] throws the following ValueError: ValueError: Object arrays cannot be loaded when allow_pickle=False  However, enabling pickle on numpy.load resolves this issue. Pickling is not discussed within the numpy.savez and numpy.savez_compressed documents...which makes me wonder why pickle is required to load the data. Do numpy.savez and numpy.savez_compressed use pickle automatically behind the scenes?

Answer: Since you have dtype=object for that, pickle will be used (serializing Python objects). Serializing with pickle is allowed by default when saving, but deserializing pickles must be explicitly requested when loading. That's because loading pickled data can execute arbitrary code, and for untrusted input this would be a security concern.
Question: The question is simply how to reproduce this: import typing a = [1, 2, 3] cls = typing.Annotated[int, *a]  or even this: import typing cls1 = typing.Annotated[int, 1, 2, 3] unann_cls = typing.get_args(cls1)[0] metadata = cls1.__metadata__ cls2 = typing.Annotated[unann_cls, *metadata]  in Python 3.9-3.10. Annotated[int, *a] is a syntax error in <3.11 so typing_extensions.Annotated shouldn't help here. "Nested Annotated types are flattened" suggests the following code: cls2 = unann_cls for m in metadata: cls2 = typing.Annotated[cls2, m]  and it seems to work but surely there should be a more clean way?

Answer: In the expression obj[1, 2, 3]  1, 2, 3 is just a tuple literal. It's exactly the same as x = 1, 2, 3 obj[x]  We're simply passing the tuple (1, 2, 3) to __getitem__. To get the behavior you want, you can wrap the tuple literal with parentheses so that the syntax for sequence unpacking inside a tuple literal kicks in: >>> typing.Annotated[(int, *a)] typing.Annotated[int, 1, 2, 3]
Question: I have a pandas data frame, and a list. The pandas data frame has 2 columns State and dates. State Dates 0 1/1/2023 1 2/1/2023 2 3/1/2023 3 4/1/2023 0 1/1/2023 1 2/1/2023 0 1/1/2023 1 2/1/2023 2 3/1/2023 0 1/1/2023 1 2/1/2023 2 3/1/2023 3 4/1/2023 4 5/1/2023 5 6/1/2023 ... country = [A, B, C, D,...]  Every time State is 0 , it should also add new item from the list corresponding to the iteration, in a new column called 'country'. State Dates country 0 1/1/2023 A 1 2/1/2023 A 2 3/1/2023 A 3 4/1/2023 A 0 1/1/2023 B 1 2/1/2023 B 0 1/1/2023 C 1 2/1/2023 C 2 3/1/2023 C 0 1/1/2023 D 1 2/1/2023 D 2 3/1/2023 D 3 4/1/2023 D 4 5/1/2023 D 5 6/1/2023 D  How can get to the result above?

Answer: Another solution: country = ["A", "B", "C", "D"] df["Country"] = df.groupby(df["State"].eq(0).cumsum())["State"].transform( lambda _, i=iter(country): next(i, None) ) print(df)  Prints:  State Dates Country 0 0 1/1/2023 A 1 1 2/1/2023 A 2 2 3/1/2023 A 3 3 4/1/2023 A 4 0 1/1/2023 B 5 1 2/1/2023 B 6 0 1/1/2023 C 7 1 2/1/2023 C 8 2 3/1/2023 C 9 0 1/1/2023 D 10 1 2/1/2023 D 11 2 3/1/2023 D 12 3 4/1/2023 D 13 4 5/1/2023 D 14 5 6/1/2023 D
Question: Unfortunately due to some internal politics within neo4j, the py2neo project is now EOL and was deleted from pypi. See this twitter thread. Is there anyone who might have forked the GitHub repository?

Answer: You can see updates here https://community.neo4j.com/t/farewell-py2neo-what-happens-now/64419 Copied from Above link,  https://github.com/overhangio/py2neo, https://github.com/SarLecobee/py2neo, https://github.com/neo4j-field/py2neo,  And One can see here as well, https://www.reddit.com/r/Neo4j/comments/174jl66/py2neo_no_longer_available/