From a3fa1dd772b210b9331b9c71d20a50487572e6eb Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 22 Nov 2024 18:42:46 +0000 Subject: [PATCH] differences for PR #32 --- 2-code-generation-optimization.md | 260 ++++++++++++++++++------------ episode2.pptx | Bin 10556117 -> 10561508 bytes md5sum.txt | 2 +- ~$episode2.pptx | Bin 0 -> 165 bytes 4 files changed, 162 insertions(+), 100 deletions(-) create mode 100644 ~$episode2.pptx diff --git a/2-code-generation-optimization.md b/2-code-generation-optimization.md index 98e67b5..2f26c07 100644 --- a/2-code-generation-optimization.md +++ b/2-code-generation-optimization.md @@ -28,6 +28,21 @@ Codeium accelerates software development through three key modes: Command, Chat, Please note that while using Python is not required since Codeium supports multiple programming languages, all exercises and solutions will be provided in Python. +::::::::::::::::::::::::::::::::::::: callout + +### Code Optimization + +Code optimization is the process of making your code faster (reducing runtime), more efficient (using fewer resources like memory and disk), and/or more readable (easier for developers to maintain). Some common strategies for code optimization include: + +- **Algorithmic optimization**: Improving the efficiency of algorithms to reduce the time or space complexity. *Example*: Reducing time complexity from O(n²) to O(n log n) by choosing the right sorting algorithm. +- **Code refactoring**: Eliminate redundancy, improve readability, and enhance maintainability without changing the code's functionality. *Example*: Replace nested loops with more concise operations like `map`, `filter`, or comprehensions. +- **Memory optimization**: Reducing memory usage by optimizing data structures, avoiding memory leaks, and minimizing unnecessary allocations. *Example*: Using generators instead of lists to avoid storing all elements in memory. +- **Parallelism and concurrency**: Utilize parallel processing or multithreading to split tasks. *Example*: Process chunks of data simultaneously using `multiprocessing` in Python. + +Much more can be said about code optimization, but these are some common strategies to keep in mind as you work with Codeium. + +::::::::::::::::::::::::::::::::::::::: + ## Context Awareness Context awareness is one of Codeium’s most powerful features, allowing it to offer personalized and highly relevant suggestions by pulling information from various sources. Traditionally, generating code required training large LLMs on specific codebases, which is resource-intensive and not scalable for individual users. However, Codeium uses a more efficient method known as **retrieval-augmented generation (RAG)**. This applies across the board to Autocompete, Chat, and Command. @@ -131,6 +146,14 @@ Good: Refactor @func:rawDataTransform by turning the while loop into a for loop ![](episodes/fig/best practices chat.png){alt='Best Practices for Chat'} +::::::::::::::::::::::::::::::::::::: callout + +### 💡 Prompting Best Practices + +The prompting strategies we’re exploring here for Codeium aren’t just limited to this tool. These techniques (e.g., like being clear, concise, and specifying outputs) apply to many other AI-powered tools like ChatGPT, Copilot, and beyond. Mastering these skills will make your interactions with all AI tools more effective, no matter the platform! + +::::::::::::::::::::::::::::::::::::::::::::::: + ### Other Features - **Persistent Context**: Configure the `Context` tab in the chat panel to enable continuous contextual awareness during and across conversations. Within this tab, you’ll find: @@ -233,95 +256,135 @@ The following shortcuts can be used to speed up your workflow: ## Hands-on Practice -In the following exercises, you will have the opportunity to practice using Codeium's Command, Chat, and Autocomplete features to generate, optimize, and refactor code. +In the following exercises, you will have the opportunity to practice using Codeium's Command, Chat, and Autocomplete features to generate, optimize, and refactor code. Create a python file (for example `exercise.py`) in your IDE and follow along with the exercises. + +::::::::::::::::::::::::::::::::::::: callout + +### Jupyter Notebooks (Not Recommended) + +It is also possible to use Codeium in Jupyter Notebooks, but for the best experience, it is recommended to use Jupyter Lab after installing the officially provided [Codeium extension for JupyterLab](https://codeium.com/jupyter_tutorial). + +Even if it is possible to use Codeium in Jupyter Notebooks directly within VS Code, the experience may not be as smooth as in a standard Python files. Indeed, Windows users may encounter issues with some of the Codeium shortcuts and features. + +::::::::::::::::::::::::::::::::::::: ### Code Generation -Let's start by exploring the Command mode and generating code snippets to analyze a dataset. In Command mode, copy and paste the following text into your editor (you can also break it down in smaller pieces if you prefer): +Let's start by exploring the Command mode and generating code snippets to analyze a dataset. In Command mode, keeping the python file open, press `⌘(Command)+I` on Mac or `Ctrl+I` on Windows/Linux to open the Command prompt. Then, copy and paste the following text into your editor (you can also break it down in smaller pieces if you prefer): ```output -Load a [CO2 concentration dataset](https://datahub.io/core/co2-ppm/) from the file `co2-mm-mlo.csv` into a Pandas DataFrame, then generate descriptive statistics and visualize data distributions. You can download the dataset using the following URL: https://edu.nl/k6v7x. +Load a [CO2 concentration dataset](https://datahub.io/core/co2-ppm/) from the file `co2-mm-mlo.csv` into a Pandas DataFrame, then generate descriptive statistics and visualize data distributions. Read the dataset using the following URL: https://edu.nl/k6v7x. 1. Write a function that takes a DataFrame as input and calculates key descriptive statistics, including: - Number of rows and columns - Data types of each column - - Summary statistics (e.g., mean, minimum, maximum) for numeric columns + - Summary statistics (e.g., mean, minimum, maximum) -2. Write a function that accepts a DataFrame and a specific column as inputs. If the column is numeric (e.g., `int64`, `float64`), create a histogram to display its distribution; if categorical, create a bar plot to show category frequencies. + Compute the statistics only for the numeric columns. -3. Write a function to plot the `Average` and `Interpolated` columns on a single graph, with Date on the x-axis, to visualize their distributions over time. +2. Write a function that accepts a DataFrame and a specific column as inputs, and creates a new figure in which it plots its distribution. If the column is numeric (e.g., `int64`, `float64`), create a histogram to display its distribution; if categorical, create a bar plot to show category frequencies. Add the name of the column to the title. + +3. Write a function that creates a new figure in which it plots the `Average` and `Interpolated` columns on a single graph, with `Date` on the x-axis, to visualize their distributions over time. + +4. In the main, print nicely the information computed in 1., run the function defined in 2. on all columns, and run the function defined in 3. Use the `show()` functionality to display the figures only at the end of the main. ``` Here is what you would expect to see in the generated code: ```python -import pandas as pd import matplotlib.pyplot as plt +import pandas as pd -# Load the dataset -url = 'https://edu.nl/k6v7x' -df = pd.read_csv(url) - -def calculate_descriptive_stats(data_frame): - nrow, ncol = data_frame.shape - data_types = data_frame.dtypes - summary_stats = data_frame.describe() - return nrow, ncol, data_types, summary_stats - -def visualize_column_distribution(data_frame, column): - if data_frame[column].dtype in ['int64', 'float64']: - plt.hist(data_frame[column], bins=20, edgecolor='k') - plt.xlabel(column) - plt.ylabel('Frequency') - plt.title(f'Histogram of {column}') + +def get_descriptive_stats(df): + """ + Calculate key descriptive statistics for a given DataFrame. + """ + stats = {"nrow": df.shape[0], "ncol": df.shape[1]} + for col in df.select_dtypes(include="number").columns: + stats[col] = { + "dtype": df[col].dtype, + "mean": df[col].mean(), + "min": df[col].min(), + "max": df[col].max(), + } + return stats + + +def plot_distribution(df, column): + """ + Plot the distribution of a given column in a DataFrame. + """ + fig, ax = plt.subplots() + if df[column].dtype.kind in "bifc": + df[column].plot.hist(ax=ax, bins=50) else: - data_frame[column].value_counts().plot(kind='bar') - plt.xlabel(column) - plt.ylabel('Count') - plt.title(f'Bar Plot of {column}') - plt.show() + df[column].value_counts().plot.bar(ax=ax) + ax.set_title(column) -def plot_average_and_interpolated(data_frame): - data_frame['Date'] = pd.to_datetime(data_frame['Date']) - plt.figure(figsize=(12, 6)) - plt.plot(data_frame['Date'], data_frame['Average'], label='Average') - plt.plot(data_frame['Date'], data_frame['Interpolated'], label='Interpolated', linestyle='--') - plt.xlabel('Date') - plt.ylabel('CO2 Concentration (ppm)') - plt.title('Average vs Interpolated CO2 Concentrations Over Time') - plt.legend() - plt.grid() - plt.show() -# Example usage -nrow, ncol, data_types, summary_stats = calculate_descriptive_stats(df) -print(f'Number of rows: {nrow}, Number of columns: {ncol}') -print(f'Data types:\n{data_types}') -print(f'Summary statistics:\n{summary_stats}') +def plot_time_series(df): + """ + Plot the Average and Interpolated columns over time. + """ + fig, ax = plt.subplots() + df.plot(x="Date", y=["Average", "Interpolated"], ax=ax) + + +def main(): + url = "https://edu.nl/k6v7x" + df = pd.read_csv(url) + stats = get_descriptive_stats(df) + print(pd.DataFrame(stats).T) + for col in df.columns: + plot_distribution(df, col) + plot_time_series(df) + plt.show() -for col in df.columns: - visualize_column_distribution(df, col) -plot_average_and_interpolated(df) +if __name__ == "__main__": + main() ``` There is something wrong here, can you spot it? We will address this issue later in the "Bug Fixing" exercise, so keep it in mind as you proceed. +::::::::::::::::::::::::::::::::::::: callout + +### Pseudo-randomness 🔍 + +You may obtain slightly different results due to the pseudo-randomness of the command mode generation process. + +::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::: callout + +### Instructions 🔍 + +The instructions provided in the text were clear and precise, designed to achieve the expected results accurately using the command mode. Try experimenting with removing, rearranging, or adding details to the instructions. You’ll notice that the assistant might generate slightly different code, which occasionally may not fully meet your intended goal. + +This exercise highlights the importance of having a clear understanding of what you want to achieve when seeking help from an assistant. It allows you to refine or adjust the instructions to guide the tool effectively toward your objective. Relying too heavily on the assistant can lead to mistakes, a point we will emphasize repeatedly throughout this lesson. + +::::::::::::::::::::::::::::::::::::: + ### Docstrings Generation -Now, let's modify the `calculate_descriptive_stats()` and `visualize_column_distribution()` functions you created during the previous exercise to add a detailed docstring using Codeium's `Docstring` lens. Each docstring should: +Now, let's modify the `get_descriptive_stats()` and `plot_column_distribution()` functions' docstrings you created during the previous exercise to add further details using Codeium's `Refactor` lens. Each docstring should: - Describe the purpose of the function - Document the function’s arguments and expected data types - Explain what the function returns (if applicable) - Optionally, provide a usage example +To do this, click on the `Refactor` lens above the function definition and select the `Add docstring and comments to the code` option. Codeium will add more details to the existing docstring, making it more informative and useful. + +Note that if you don't have a docstring yet in your function definition, another lens will appear to help you generate one, the `Generate Docstring` lens. Try experimenting with both lenses to see how they can improve your code documentation. + ::::::::::::::::::::::::::::::::::::: callout ### 💡 Tip -Try experimenting with different docstring styles! For example, you could also explore the [Google-style docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) using the `Refactor` lens or the Command mode. The default style used by the `Docstring` lens should be the [NumPy-style](https://numpydoc.readthedocs.io/en/latest/format.html). +Try experimenting with different docstring styles! For example, you could also explore the [Google-style docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) using the `Refactor` lens or the Command mode. The default style used by the lenses should be the [NumPy-style](https://numpydoc.readthedocs.io/en/latest/format.html). ::::::::::::::::::::::::::::::::::::: @@ -333,62 +396,60 @@ While Command mode is not aware of the context of your code and doesn't maintain ::::::::::::::::::::::::::::::::::::: -Please note that, while you could manually write the docstring and use suggestions from Autocomplete mode (which we will cover later in this episode), this task is designed to demonstrate Codeium's `Docstring` functionality. - -Here’s an example of how the `calculate_descriptive_stats()` and the `visualize_column_distribution() `functions might look with the generated docstrings: +Here’s an example of how the `get_descriptive_stats()` and the `plot_column_distribution() `functions might look with the refactored docstrings: ```python -def calculate_descriptive_stats(data_frame): +def plot_distribution(df, column): """ - Calculate the number of rows, number of columns, data types of columns, - and descriptive statistics of a given DataFrame. + Plot the distribution of a given column in a DataFrame. + + For numerical columns, a histogram is plotted. For categorical columns, + a bar plot of the counts is plotted. Parameters ---------- - data_frame : pandas.DataFrame - The DataFrame to be analyzed + df : DataFrame + The DataFrame to plot the distribution for. + column : str + The column to plot the distribution for. Returns ------- - tuple - A tuple containing (nrow, ncol, data_types, summary_stats) + None """ - nrow, ncol = data_frame.shape - data_types = data_frame.dtypes - summary_stats = data_frame.describe() - return nrow, ncol, data_types, summary_stats + fig, ax = plt.subplots() + if df[column].dtype.kind in "bifc": + # Plot a histogram for numerical columns + df[column].plot.hist(ax=ax, bins=50) + else: + # Plot a bar plot of the counts for categorical columns + df[column].value_counts().plot.bar(ax=ax) + ax.set_title(column) -def visualize_column_distribution(data_frame, column): +def plot_column_distribution(df, column): """ - Visualize the distribution of the given column in a DataFrame. + Plot the distribution of a given column in a DataFrame. Parameters ---------- - data_frame : pandas.DataFrame - The DataFrame containing the column to be visualized + df : DataFrame + The DataFrame containing the data. column : str - The column name to be visualized - - Returns - ------- - None - - Notes - ----- - If the column is numeric (int64 or float64), a histogram is plotted. - Otherwise, a bar plot of the value counts is plotted. - """ - if data_frame[column].dtype in ["int64", "float64"]: - plt.hist(data_frame[column], bins=20, edgecolor="k") - plt.xlabel(column) - plt.ylabel("Frequency") - plt.title(f"Histogram of {column}") + The column name in the DataFrame for which to plot the distribution. + """ + # Create a new figure and axis for the plot + fig, ax = plt.subplots() + + # Check if the column is of a numeric type + if df[column].dtype.kind in "bifc": + # Plot a histogram for numeric data + df[column].plot.hist(ax=ax, bins=50) else: - data_frame[column].value_counts().plot(kind="bar") - plt.xlabel(column) - plt.ylabel("Count") - plt.title(f"Bar Plot of {column}") - plt.show() + # Plot a bar chart for categorical data + df[column].value_counts().plot.bar(ax=ax) + + # Set the title of the plot to the column name + ax.set_title(column) ``` Note that you might need to adjust the generated docstring if the function has complex logic or if the generated docstring lacks specific details about edge cases or exceptions. @@ -397,7 +458,7 @@ Note that you might need to adjust the generated docstring if the function has c ## Bug Fixing (5 min) -Look back at the code generated during the "Assisted Code Generation" section. If you look at the head of the DataFrame, what do you notice? Use the Chat feature to discuss the issue with Codeium and ask for suggestions on how to resolve it. Then run again the functions defined in the previous exercise to see if the issue has been resolved. +Look back at the code generated during the "Code Generation" section. If you look at the head of the DataFrame, what do you notice? Use the Chat feature to discuss the issue with Codeium and ask for suggestions on how to resolve it. Then run again the functions defined in the previous exercise to see if the issue has been resolved. :::::::::::::::::::::::::::::::::::::::::::::::: @@ -407,7 +468,7 @@ Look back at the code generated during the "Assisted Code Generation" section. I The issue is that the `Date` column is used as index column, causing all the other columns to shift by one. Here’s how you might discuss the issue with Codeium in the Chat: -1. **Prompt**: "The `Date` column is being used as the index, causing the other columns to shift by one. How can I resolve this issue?" +1. **Prompt**: "The `Date` column is being used as the index, causing the other columns to shift by one. How can I read the file without encourring into this issue?" 2. **Discussion**: Codeium might suggest resetting the index or using the `reset_index()` function to address the issue. Alternatively, it might recommend setting `index_col=False` when reading the CSV file to prevent the `Date` column from being used as the index. Correct example of how to resolve the issue: @@ -444,7 +505,7 @@ Or even like this: df['Avg-Int'] = df['Average'] - df['Interpolated'] ``` -This version is faster and more memory-efficient because it uses vectorized operations, which are a key feature of the pandas library. +This version is faster and more memory-efficient because it uses vectorized operations, which are a key feature of the `pandas` library. ::::::::::::::::::::::::::::::::::::: challenge @@ -454,16 +515,16 @@ Similar to the exercise above, execute the code as is to verify it works and exa ```python # Convert 'Date' column to datetime format -data['Date'] = pd.to_datetime(data['Date'], format='%Y-%m') +df['Date'] = pd.to_datetime(df['Date'], format='%Y-%m') # Filter data for a specific date range -filtered_data = data[(data['Date'] >= '2000-01-01') & (data['Date'] <= '2010-12-31')] +filtered_df = df[(df['Date'] >= '2000-01-01') & (df['Date'] <= '2010-12-31')] # Extract the year value from the 'Date' column -filtered_data['Year'] = filtered_data['Date'].dt.year +filtered_df['Year'] = filtered_df['Date'].dt.year # Group data by year and calculate the average CO2 level for each year -avg_co2_per_year = filtered_data.groupby('Year')['Interpolated'].mean() +avg_co2_per_year = filtered_df.groupby('Year')['Interpolated'].mean() # Plot the results plt.figure(figsize=(10, 6)) @@ -485,12 +546,13 @@ plt.show() ```python # Convert 'Date' column to datetime format and filter data for a specific date range -filtered_data = data[(pd.to_datetime(data['Date'], format='%Y-%m') >= '2000-01-01') & - (pd.to_datetime(data['Date'], format='%Y-%m') <= '2010-12-31')] +filtered_df = df[ + (pd.to_datetime(df['Date'], format='%Y-%m') >= '2000-01-01') & + (pd.to_datetime(df['Date'], format='%Y-%m') <= '2010-12-31')] # Group data by year and calculate the average CO2 level for each year -avg_co2_per_year = filtered_data.groupby(pd.to_datetime(filtered_data['Date'], format='%Y-%m').dt.year)['Interpolated'].mean() +avg_co2_per_year = filtered_df.groupby(pd.to_datetime(filtered_df['Date'], format='%Y-%m').dt.year)['Interpolated'].mean() # Plot the results @@ -507,7 +569,7 @@ plt.show() - Combined the `pd.to_datetime` conversion and filtering steps into one. -- Removed the unnecessary `filtered_data['Year']` column and used the `dt.year` accessor to extract the year from the `'Date'` column. +- Removed the unnecessary `filtered_df['Year']` column and used the `dt.year` accessor to extract the year from the `'Date'` column. - Simplified the plotting code by using the `plot` method of the Series object and removing the unnecessary `plt.figure` call. diff --git a/episode2.pptx b/episode2.pptx index a681b58f911fc52f459a5c0d77c0f5263ec21537..1f2386961d47f6f451c0a8ec1f7e5661ec694179 100644 GIT binary patch delta 21855 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 wk7;uZR2LFosZKj*u?M_fgfaAu+b=1uw#Wj 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 E0FrZ00RR91 diff --git a/md5sum.txt b/md5sum.txt index b6c2b45..4dc1182 100644 --- a/md5sum.txt +++ b/md5sum.txt @@ -5,7 +5,7 @@ "index.md" "34399a5e151cea103c92aa7767f4c118" "site/built/index.md" "2024-09-13" "links.md" "8184cf4149eafbf03ce8da8ff0778c14" "site/built/links.md" "2022-04-22" "episodes/1-introduction-ai-coding.md" "94f89961042798b06550db4272371638" "site/built/1-introduction-ai-coding.md" "2024-10-28" -"episodes/2-code-generation-optimization.md" "b4bdd36643ceff7c94d63b212ae55a94" "site/built/2-code-generation-optimization.md" "2024-11-21" +"episodes/2-code-generation-optimization.md" "75f069823751cc0ecb7168d4bc5c2eb5" "site/built/2-code-generation-optimization.md" "2024-11-22" "episodes/3-ethical-and-security-considerations.md" "5540ef40fd86510c8eba8273204334c5" "site/built/3-ethical-and-security-considerations.md" "2024-10-28" "instructors/instructor-notes.md" "d96cb9e76302dee237d0897fb5c1b1a7" "site/built/instructor-notes.md" "2024-09-13" "learners/reference.md" "86cca05410972bf6feb3e65095c6c89b" "site/built/reference.md" "2024-10-23" diff --git a/~$episode2.pptx b/~$episode2.pptx new file mode 100644 index 0000000000000000000000000000000000000000..b0f354da0361cd001b820e98d8e63e1efc7d1851 GIT binary patch literal 165 zcmd;g&n(T!OjK|#%1_SB&&y;`APVp^xHDujlrrQ1$wUSP24{vMhJ1!(ATOUG4@fFd G6#@XvD-|IC literal 0 HcmV?d00001