eshangj/stackoverflow_q_and_a_sample huggingface dataset:
Question: _func is designed to return two columns: from polars.type_aliases import IntoExpr, IntoExprColumn import polars as pl def _func(x: IntoExpr): x1 = x+1 x2 = x+2 return pl.struct([x1, x2]) df = pl.DataFrame({"test": np.arange(1, 11)}) df.with_columns( _func(pl.col("test")).alias(["test1", "test2"]) )  I have tried to wrap the return values using pl.struct but it didn't work. Expected output: shape: (10, 3) test test1 test2 i32 i32 i32 1 2 3 2 3 4 3 4 5 4 5 6 5 6 7 6 7 8 7 8 9 8 9 10 9 10 11 10 11 12 

Answer: I'm assuming that you cannot or don't want to change the function, so we need to work with sequence of expressions returned by this function. Also I want the answer to be able to accommodate for more than 2 columns, so I don't have to specifically alias each column. The problem in your case is at the end you have a sequence of Expr with the same name, so you need to rename them at some point before executing. Solution might depend on what kind of names do you plan to use for your columns. You can do something like this: def _func(x: IntoExpr): x1 = x+1 x2 = x+2 return x1, x2 df.with_columns( x.alias(f"test{i+1}") for i,x in enumerate(_func(pl.col("test"))) ) # alternatevely # df.with_columns( # x.name.suffix(f"{i+1}") for i,x in enumerate(_func(pl.col("test"))) #) ┌──────┬───────┬───────┐ │ test ┆ test1 ┆ test2 │ │ --- ┆ --- ┆ --- │ │ i32 ┆ i32 ┆ i32 │ ╞══════╪═══════╪═══════╡ │ 1 ┆ 2 ┆ 3 │ │ 2 ┆ 3 ┆ 4 │ │ 3 ┆ 4 ┆ 5 │ │ 4 ┆ 5 ┆ 6 │ │ 5 ┆ 6 ┆ 7 │ │ 6 ┆ 7 ┆ 8 │ │ 7 ┆ 8 ┆ 9 │ │ 8 ┆ 9 ┆ 10 │ │ 9 ┆ 10 ┆ 11 │ │ 10 ┆ 11 ┆ 12 │ └──────┴───────┴───────┘  For custom names you can use zip: f.with_columns( x.alias(n) for x, n in zip(_func(pl.col('test')), ["a","b"]) ) ┌──────┬─────┬─────┐ │ test ┆ a ┆ b │ │ --- ┆ --- ┆ --- │ │ i32 ┆ i32 ┆ i32 │ ╞══════╪═════╪═════╡ │ 1 ┆ 2 ┆ 3 │ │ 2 ┆ 3 ┆ 4 │ │ 3 ┆ 4 ┆ 5 │ │ 4 ┆ 5 ┆ 6 │ │ 5 ┆ 6 ┆ 7 │ │ 6 ┆ 7 ┆ 8 │ │ 7 ┆ 8 ┆ 9 │ │ 8 ┆ 9 ┆ 10 │ │ 9 ┆ 10 ┆ 11 │ │ 10 ┆ 11 ┆ 12 │ └──────┴─────┴─────┘  Or you can use the fact that with_columns() accepts **named_exprs as an argument,convert list of expressions into dict and unpack it: df.with_columns( **dict(zip(['a','b'], _func(pl.col('test')))) ) ┌──────┬─────┬─────┐ │ test ┆ a ┆ b │ │ --- ┆ --- ┆ --- │ │ i32 ┆ i32 ┆ i32 │ ╞══════╪═════╪═════╡ │ 1 ┆ 2 ┆ 3 │ │ 2 ┆ 3 ┆ 4 │ │ 3 ┆ 4 ┆ 5 │ │ 4 ┆ 5 ┆ 6 │ │ 5 ┆ 6 ┆ 7 │ │ 6 ┆ 7 ┆ 8 │ │ 7 ┆ 8 ┆ 9 │ │ 8 ┆ 9 ┆ 10 │ │ 9 ┆ 10 ┆ 11 │ │ 10 ┆ 11 ┆ 12 │ └──────┴─────┴─────┘
Question: I am sorry if this is a duplicate, but I didn't find a suitable answer for this problem. If have a bytes object in python, like this: b'\n\x00\x00\x00\x01\x00\x00\x00TEST\xa2~\x08A\x83\x11\xe3@\x05\x00\x00\x00\x03\x00\x00\x00TEST\x91\x9b\xd1?\x1c\xaa,@'  It contains first a certain number of integer (4bytes) then a string with 4 characters and then a certain number of floats (4bytes). This is repeated a certain number of times which each correspond to a new row of data. The format of each row is the same and known. In the example this 2 rows of 2 integers, 1 string and 2 floats. My question is, if there is a way to convert this kind of data to a pandas DataFrame directly. My current approach was to first read all values (e.g. with struct.Struct.unpack) and place them in a list of lists. This however seem rather slow, especially for a large number of rows.

Answer: This works fine for me: import numpy as np import pandas as pd data = b'\n\x00\x00\x00\x01\x00\x00\x00TEST\xa2~\x08A\x83\x11\xe3@\x05\x00\x00\x00\x03\x00\x00\x00TEST\x91\x9b\xd1?\x1c\xaa,@' dtype = np.dtype([ ('int1', np.int32), ('int2', np.int32), ('string', 'S4'), ('float1', np.float32), ('float2', np.float32), ]) structured_array = np.frombuffer(data, dtype=dtype) df = pd.DataFrame(structured_array) df['string'] = df['string'].str.decode('utf-8') print(df)  And it gives me this following output:     int1 int2 string float1 float2     0 10 1 TEST 8.530916 7.095888   1 5 3 TEST 1.637560 2.697883
Question: For context, I have a function that matches keys in a dictionary to perform certain action; to match item keys, the function accepts either a sequence of keys to match, or a function that recognizes those keys. I'm wondering if I can use the match-case pattern for it. I try something like: def process_fields(dataset,function,fields): """Apply function to selected values of a dictionary fields can be a list of keys whose values shall be processed, or a predicate that returns True for the targeted fields.""" match fields: case list() | set() | tuple(): key_matcher = lambda x:x in fields case <what I'm looking for>: key_matcher=fields walk_items(dataset,key_matcher,function)  So far I've tried:  case callable(function): key_matcher=function   case typing.Callable(function): key_matcher=function  I can't find what I need in the official documentation. I'm I missing something or it's not doable? Example is here to avoid too dry abstraction. Note that I'm NOT looking for alternatives to solve that particular problem, I can perfectly do it myself; I'm looking to find out if it exist a way to use that python structure in particular. Edit: Even though the function itself is not the focus of the post, I've added a docstring and simplified a bit to clarify the example.

Answer: If you want to test if an object is Callable then: from collections.abc import Callable def func(): pass f = func match f: case Callable(): print("Yes it's callable")
Question:  Logging Error: Failed to initialize logging system. Log messages may be missing. If this issue persists, try setting IDEPreferLogStreaming=YES in the active scheme actions environment variables.  Has anyone else encountered this message? Where is IDEPreferLogStreaming located? I don't know what any of this means. It's building my app successfully but then loading it like its a computer using floppy discs (crazy slow). Any ideas? I tried wiping my OS and reinstalling. I've reinstalled Xcode twice now. Nothing. A colleague of mine is working on the same SwifUI project with no issues.

Answer: To find IDEPreferLogStreaming, you need to go to Product -> Scheme -> Edit Scheme and then add it as a new Environment Variable yourself. IDEPreferLogStreaming=YES  For me it didnt solve the issue though --- [Edit: it works for me now as well. Probably I was to quick saying it doesnt. Thanks for your feedback.]
Question: I need the current timestamp in EST but the current_timestamp() is returning PST. Tried the following code but it's not working and showing 6 hours before EST time: # Import the current_timestamp function from pyspark.sql.functions import from_utc_timestamp # Set the timezone to EST spark.conf.set("spark.sql.session.timeZone", "EST") # Get the current timestamp in EST current_timestamp_est = spark.sql("SELECT from_utc_timestamp(current_timestamp(), 'EST') as current_timestamp_est") # Show the current timestamp in EST current_timestamp_est.show(truncate = False)  Also tried the below code. But the time is coming as 2024-03-11 23:16:04.589275-04:00. Why it's coming with -4:00? Is there a way to get rid of the -4:00? from datetime import datetime from pytz import timezone est = timezone('US/Eastern') now_est = datetime.now(est) #now_est1 = now_est[:26] print(now_est)  Any other way to get the current timestamp in EST in a variable?

Answer: To get rid of the -04:00 you can just use .strftime() in your second approach: from datetime import datetime from pytz import timezone est = timezone('US/Eastern') now_est = datetime.now(est).strftime('%Y-%m-%d %H:%M:%S') print(now_est) Output: 2024-04-04 09:42:58  Now, for the first approach instead of setting EST as the timezone - it's preferred to point out a location around the globe like America/New_York to get rid of the offset value -04:00 as follows: spark.conf.set("spark.sql.session.timeZone", "America/New_York") current_timestamp_est = spark.sql("SELECT current_timestamp() as current_timestamp_est") current_timestamp_est.show(truncate=False) Output: +--------------------------+ |current_timestamp_est | +--------------------------+ |2024-04-04 09:42:12.082136| +--------------------------+
Question: I have a project using Celery with Redis backend to manage tasks. For local development I am trying to set up Celery with filesystem as broker instead of Redis. However, when I run Celery worker, it creates me control folder in the root directory with the following contents: /control ├── celery.pidbox.exchange ├── Q1.exchange ├── Q2.exchange ├── ...  I have trouble finding any resources on what it is and for what it is used exactly. My goal is to possibly move this folder to another location (ex. .celery/ folder), so that it does not sit in root directory. Here is my Celery configuration: class CeleryLocalConfig: include = ["app.tasks"] broker_url = "filesystem://" result_backend = "file://.celery/broker/results" broker_transport_options = { "data_folder_in": ".celery/broker/out", "data_folder_out": ".celery/broker/out", "queue_order_strategy": "sorted" } celery_app = Celery(__name__) celery_app.config_from_object(CeleryLocalConfig)  So far I have tried:  Running Celery worker from different directory than root, but then worker doesn't receive any tasks.  Providing --workdir parameter when running Celery worker, but it seem to create different paths between Celery worker and Celery app and therefore fails.  

Answer: Setting a control_folder field did the trick for me: CELERY_BROKER_TRANSPORT_OPTIONS = { "data_folder_in": os.path.join(BASE_DIR, ".celery"), "data_folder_out": os.path.join(BASE_DIR, ".celery"), "control_folder": os.path.join(BASE_DIR, ".celery"), }  So for you, I suppose, it would be: broker_transport_options = { "data_folder_in": ".celery/broker/out", "data_folder_out": ".celery/broker/out", "queue_order_strategy": "sorted", "control_folder": ".celery/broker/out", }
Question: I have a FastAPI + SQLAlchemy project and I'm using Pytest for writing unit tests for the APIs. In each test function, I create some data in some tables (user table, post table, comment table, etc) using SQLAlchemy. These created data in each test function will remain in the tables after test function finished and will affect on other test functions. For example, in the first test function I create 3 posts, and 2 users, then in the second test functions, these 3 posts and 2 users remained on the tables and makes my test expectations wrong. Following is my fixture for pytest: @pytest.fixture def session(engine): Session = sessionmaker(bind=engine) session = Session() yield session session.rollback() # Removes data created in each test method session.close() # Close the session after each test  I used session.rollback() to remove all created data during session, but it doesn't remove data. And the following is my test functions: class TestAllPosts(PostBaseTestCase): def create_logged_in_user(self, db): user = self.create_user(db) return user.generate_tokens()["access"] def test_can_api_return_all_posts_without_query_parameters(self, client, session): posts_count = 5 user_token = self.create_logged_in_user(session) for i in range(posts_count): self.create_post(session) response = client.get(url, headers={"Authorization": f"Bearer {user_token}"}) assert response.status_code == 200 json_response = response.json() assert len(json_response) == posts_count def test_can_api_detect_there_is_no_post(self, client, session): user_token = self.create_logged_in_user(session) response = client.get(url, headers={"Authorization": f"Bearer {user_token}"}) assert response.status_code == 404  In the latest test function, instead of getting 404, I get 200 with 5 posts (from the last test function) How can I remove the created data in each test function after test function finished?

Answer: The problem is that there are multiple sessions. One is used by your tests. The other one(s) is/are used by the server. Because you are using client.get, you are sending a request to the server, which will use its own database session.  To solve your problem you can just truncate all tables at the end of each test: https://stackoverflow.com/a/25220958/5521670  @pytest.fixture def session(engine): Session = sessionmaker(bind=engine) session = Session() yield session # Remove any data from database (even data not created by this session) with contextlib.closing(engine.connect()) as connection: transaction = connection.begin() connection.execute(f'TRUNCATE TABLE {",".join(table.name for table in reversed(Base.metadata.sorted_tables)} RESTART IDENTITY CASCADE;')) transaction.commit() session.rollback() # Removes data created in each test method session.close() # Close the session after each test   Another alternative would be to make the server use your test session (just like the FastAPI documentation suggests): https://fastapi.tiangolo.com/advanced/testing-database/  def override_get_db(): try: db = TestingSessionLocal() yield db finally: db.close() app.dependency_overrides[get_db] = override_get_db
Question: I'm trying to reproduce the code from documentation: https://docs.llamaindex.ai/en/stable/examples/customization/llms/AzureOpenAI.html and receive the following error after index = VectorStoreIndex.from_documents(documents): raise ValueError(f"Unknown document type: {type(document)}") ValueError: Unknown document type: <class 'llama_index.legacy.schema.Document'>  Due to the fact that all these generative ai libraries are being constantly updated, I have to switch the import of SimpleDirectoryReader and make it like from llama_index.legacy.readers.file.base import SimpleDirectoryReader All the rest is actually the same with tutorial (using llama_index==0.10.18 and python of version 3.9.16). I have spent already several hours on that and actually don't have ideas how should I proceed. So if somebody can assist with that - it would be super helpful :) Many thanks in advance.

Answer: The error occurs because of the type of document you are passing for VectorStoreIndex.from_documents(). When you import SimpleDirectoryReader from legacy modules, the type of document is llama_index.legacy.schema.Document.  You are passing that to VectorStoreIndex, which is imported from core modules: from llama_index.core import VectorStoreIndex. The document you referred to is correct for core modules, and you can import SimpleDirectoryReader as from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, and everything will work fine. If you wish to use legacy modules, then use the code below. from llama_index.legacy.llms.azure_openai import AzureOpenAI from llama_index.legacy.embeddings.azure_openai import AzureOpenAIEmbedding from llama_index.legacy import SimpleDirectoryReader, VectorStoreIndex, ServiceContext import logging import sys logging.basicConfig( stream=sys.stdout, level=logging.INFO ) # logging.DEBUG for more verbose output logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout)) api_key = "3c9xxxyyyyzzzzzssssssdb9" azure_endpoint = "https://<resource_name>.openai.azure.com/" api_version = "2023-07-01-preview" llm = AzureOpenAI( model="gpt-4", deployment_name="gpt4", api_key=api_key, azure_endpoint=azure_endpoint, api_version=api_version, ) # You need to deploy your own embedding model as well as your own chat completion model embed_model = AzureOpenAIEmbedding( model="text-embedding-ada-002", deployment_name="embeding1", api_key=api_key, azure_endpoint=azure_endpoint, api_version=api_version, ) documents = SimpleDirectoryReader(input_files=["./data/s1.txt"]).load_data() type(documents[0]) service_context = ServiceContext.from_defaults( llm=llm, embed_model=embed_model ) index = VectorStoreIndex.from_documents(documents, service_context=service_context)  Output: query = "What is the model name and who updated it last?" query_engine = index.as_query_engine() answer = query_engine.query(query) print("query was:", query) print("answer was:", answer)   Here, when using legacy modules, all tools and models should be imported from the same legacy modules, and an additional service context is used for the vector store index.
Question: I'm looking at the standard library documentation, and I see that from typing import Sequence is just calling collections.abc under the hood. Now originally, there was a deprecation warning/error and migration from the collections package to collections.abc for some abstract classes. See here. However, now that the abstractions have settled in a new location, is it fine to use either? I see from collections.abc import [etc] in the codebase, and I wonder if it would be more practical to just import from typing when trying to do type annotations? Cython source code: Sequence = _alias(collections.abc.Sequence, 1)

Answer:  However, now that the abstractions have settled in a new location, is it fine to use either?  It's better not to do so. The documentation specifically says:  class typing.Sequence(Reversible[T_co], Collection[T_co]) Deprecated alias to collections.abc.Sequence. Deprecated since version 3.9: collections.abc.Sequence now supports subscripting ([])  If it's deprecated, it may be removed in the next versions of Python. So go with collections.abc generic classes.
Question: As title says, Let's say I have following dataframe import pandas as pd df = pd.DataFrame({'UID':['A','B','C','D'],'FlagVal':[0,100,50,90],'TrueVal':[1000,1000,1000,1000]}) ndf = df.loc[~df['FlagVal'].between(0,100,inclusive='neither')] mdf = df.loc[df['FlagVal'].between(0,100,inclusive='neither')]  I want to split records into two where FlagVal is between 0 and 100. i.e. mdf , and perform a few calculations - def split_record(row): gtd = row.copy() ungtd = row.copy() gtd['UID'] = row['UID'] + '_T1' gtd['Flag'] = 'Y' ungtd['UID'] = row['UID'] + '_T2' ungtd['Flag'] = '' gtd['TrueVal'] = float(gtd['TrueVal'])*(float(gtd['FlagVal'])/100.0) ungtd['TrueVal'] = float(ungtd['TrueVal'])*(1 - (float(ungtd['FlagVal'])/100.0)) gtd['FlagVal'] = 100 ungtd['FlagVal'] = 0 result_data = pd.DataFrame([gtd, ungtd]) return result_data split_df = pd.concat([split_record(row) for _, row in mdf.iterrows()], ignore_index=True)  then merge with 'ndf'. This works just fine for ~1000 records or so but it takes a toll when record count is in millions. I tried using apply function with axis=1, but not sure how to merge it with data again. Can you point me to a correct function to optimize it?

Answer: You can create split_df in two steps (this will be very fast): # create the 100% part: mdf_100 = pd.DataFrame({"TrueVal": mdf["FlagVal"].div(100) * mdf["TrueVal"]}).assign( FlagVal=100, UID=mdf["UID"] + "_T1", Flag="Y" ) # create the 0% part: mdf_0 = pd.DataFrame( {"TrueVal": (1 - mdf["FlagVal"].div(100)) * mdf["TrueVal"]} ).assign(FlagVal=0, UID=mdf["UID"] + "_T2", Flag="") split_df = pd.concat([mdf_100, mdf_0]).sort_index() print(split_df)  Prints:  TrueVal FlagVal UID Flag 2 500.0 100 C_T1 Y 2 500.0 0 C_T2 3 900.0 100 D_T1 Y 3 100.0 0 D_T2   EDIT: With multiple TrueValX columns: cols = ["TrueVal1", "TrueVal2", "TrueVal3"] # create the 100% part: mdf_100 = pd.DataFrame({c: mdf["FlagVal"].div(100) * mdf[c] for c in cols}).assign( FlagVal=100, UID=mdf["UID"] + "_T1", Flag="Y" ) # create the 0% part: mdf_0 = pd.DataFrame({c: (1 - mdf["FlagVal"].div(100)) * mdf[c] for c in cols}).assign( FlagVal=0, UID=mdf["UID"] + "_T2", Flag="" ) split_df = pd.concat([mdf_100, mdf_0]).sort_index() print(split_df)  Prints:  TrueVal1 TrueVal2 TrueVal3 FlagVal UID Flag 2 500.0 1000.0 1500.0 100 C_T1 Y 2 500.0 1000.0 1500.0 0 C_T2 3 900.0 1800.0 2700.0 100 D_T1 Y 3 100.0 200.0 300.0 0 D_T2  Input df:  UID FlagVal TrueVal1 TrueVal2 TrueVal3 0 A 0 1000 2000 3000 1 B 100 1000 2000 3000 2 C 50 1000 2000 3000 3 D 90 1000 2000 3000
Question: I'm trying to use the Langchain ReAct Agents and I want to give them my pinecone index for context. I couldn't find any interface that let me provide the LLM that uses the ReAct chain my vector embeddings as well. Here I set up the LLM and retrieve my vector embedding. llm = ChatOpenAI(temperature=0.1, model_name="gpt-4") retriever = vector_store.as_retriever(search_type='similarity', search_kwargs={'k': k})  Here I start my ReAct Chain. prompt = hub.pull("hwchase17/structured-chat-agent") agent = create_structured_chat_agent(llm, tools, prompt) agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) result = agent_executor.invoke( { "input": question, "chat_history": chat_history } )  Before using the ReAct Agent, I used the vector embedding like this. crc = ConversationalRetrievalChain.from_llm(llm, retriever) result = crc.invoke({'question': systemPrompt, 'chat_history': chat_history}) chat_history.append((question, result['answer']))  Is there any way to combine both methods and have a ReAct agent that also uses vector Embeddings?

Answer: You can specify the retriever as a tool for the agent. Example: from langchain.tools.retriever import create_retriever_tool retriever = vector_store.as_retriever(search_type='similarity', search_kwargs={'k': k}) retriever_tool = create_retriever_tool( retriever, "retriever_name", "A detailed description of the retriever and when the agent should use it.", ) tools = [retriever_tool] agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)  References:  Agent > Retriever (LangChain)
Question: How do I convert a MultiIndex DataFrame to a Standard index DF? import pandas as pd df1 = pd.DataFrame({'old_code': ['00000001', '00000002', '00000003', '00000004'], 'Desc': ['99999991', '99999992 or 99999922', 'Use 99999993 or 99999933', '99999994']}, ) df1.set_index('old_code', inplace=True) df2=df1["Desc"].str.extractall(r"(?P<new_code>\d{7,9})") print(df2.head(10))  My output looks like this old_code match new_code 00000001 0 99999991 00000002 0 99999992 1 99999922 00000003 0 99999993 1 99999933 00000004 0 99999994  I'm trying to get it in a format like this? old_code new_code 00000001 99999991 00000002 99999992 00000002 99999922 00000003 99999993 00000002 99999933 00000004 99999994 

Answer: You can drop the second level index and then reset the index: print(df2.droplevel(1).reset_index())  Prints:  old_code new_code 0 00000001 99999991 1 00000002 99999992 2 00000002 99999922 3 00000003 99999993 4 00000003 99999933 5 00000004 99999994
Question: Given a data frame, I need to create a new column 'flag' which will have value True in row i if i is not in any of the lists in column 'id' and False otherwise. For the example below, flag for rows 1, 3, 5, and 6 should be True. I attempt it with lambda, but cannot get it work. import pandas as pd pos = pd.DataFrame(columns=['id', 'pred']) pos.loc[1,'id'] = [4, 4] pos.loc[2,'id'] = [2] pos.loc[3,'id'] = [2, 4] pos.loc[4,'id'] = [2] pos.loc[5,'id'] = [2, 4] pos.loc[6,'id'] = [4] for i in range(0, len(pos)): pos['flag'] = pos.apply(lambda x: int(i in x['id']), axis=True) print(pos)   id pred flag 1 [4, 4] NaN False 2 [2] NaN False 3 [2, 4] NaN False 4 [2, 6] NaN False 5 [2, 6] NaN False 6 [6] NaN False 

Answer: With (~)isin/explode: pos["flag"] = ~pos.index.isin(pos["id"].explode()) # .astype(int) ?  Output :  id pred flag 1 [4, 4] NaN True 2 [2] NaN False 3 [2, 4] NaN True 4 [2] NaN False 5 [2, 4] NaN True 6 [4] NaN True [6 rows x 3 columns]
Question: I am using quarto, python, and jupyter lab/notebook to be able to create reproducible reports. Our reports include a preface page before the title page with additional information about what is included in the report. So, how do I place content before the title page? The final document will be a .pdf. After much googling I suspect it has something to do with modifying before-body.tex but it wasn't clear to me if or how I could move the title page.

Answer: Yes, you need to use before-body.tex latex template partials. Include your preface contents before the title. before-body.tex $if(has-frontmatter)$ \frontmatter $endif$ % ----------- PREFACE ---------- \begin{center} \Large{Preface} \end{center} Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut vulputate bibendum mauris vel aliquam. Fusce vulputate non ligula vitae accumsan % ------------------------------- $if(title)$ $if(beamer)$ \frame{\titlepage} $else$ \maketitle $endif$ $if(abstract)$ \begin{abstract} $abstract$ \end{abstract} $endif$ $endif$  And, then use this template partial in the YAML of the ipynb file.