Skip to content

Commit

Permalink
adds a few ChatGPT-generated exercises
Browse files Browse the repository at this point in the history
  • Loading branch information
CSchoel committed Mar 20, 2024
1 parent f3579a0 commit 7219675
Show file tree
Hide file tree
Showing 8 changed files with 639 additions and 0 deletions.
95 changes: 95 additions & 0 deletions notes/chat_gpt_prompts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# ChatGPT prompts for exercise generation

## Base prompt

You are a teacher of a introductory Python course for computational linguists. You use type hinting and Python features up to Python 3.8. Since the course is quite large, you use an automatic grading system using unit tests with the `unittest` module.

Please write a programming exercise for your students. Be precise in the wording. The programming exercise should take no more than 1 h to complete. Students should write a function that is then tested with a unit test. Please also provide the code for the unit test.

For your answer, please use the same structure as the following example delimited by <exercise> and </exercise>:

<exercise>
<description>
---
title: Batchify
author:
- ChatGPT
- Christopher Schölzel
keywords:
- language: python
- course: Introduction to Python for computational linguists
lang: en-US
solution-size: 8 # measured in lines of code
id: 5111a717-e313-49b5-b95f-8bec5a07e30e
---

# Batchify

Implement a function `batchify(input: str, batchSize: int) -> List[str]` in `batchify.py` which gets a string as input, as well as a number `batchSize`. This function should split the `input` into chunks of `batchSize` characters length.

Example:

```python
result = batchify("ABCDEFGH",4)
print(result) # -> ['ABCD','EFGH']

result = batchify("ABCDEFGH",3)
print(result) # -> ['ABC', 'DEF', 'GH']
```


> Tip: Use the slicing operator.
Make sure to save the function in a file called `batchify.py` so that it can be imported with `from batchify import batchify`.

</description>
<unittest>

```python
import unittest

from batchify import batchify

class TestSplitting(unittest.TestCase):

def testBatch4(self):
input = "Hallo Welt!"
result = batchify(input, 4)
self.assertEqual(["Hall", "o We", "lt!"], result)

def testBatch2(self):
input = "Hallo Welt!"
result = batchify(input, 2)
self.assertEqual(["Ha","ll", "o ", "We", "lt", "!"], result)

if __name__ == '__main__':
unittest.main()
```

</unittest>
<example_solution>

```python
from typing import List

def batchify(input: str, batchSize: int) -> List[str]:
batches = []
for i in range(0, len(input), batchSize):
batches.append(input[i: i + batchSize])
return batches
```
</example_solution>
</exercise>

Please answer with the same structure as above for the following type of exercise: Create a ngram class that can generate an ngram model and make predictions based on it.

## Variants of final Paragraph

* Please answer with the same structure as above but choose a different exercise.
* Please answer with the same structure as above but choose a different exercise.
The exercise should be more complex than the example.
* Please answer with the same structure as above for the following type of exercise: Pig Latin translation: Write a function that translates a given sentence into Pig Latin.

## Prompts for exercise ideas

Please give me examples of programming exercises for an introductory Python course for computational linguists. The exercises should require to write a single function or class. Please list 10 easy, 10 medium, and 10 hard examples. Just write one sentence per example that gives a general idea what the exercise should be about. The exercises should only require to use the Python standard library and take no more than one hour.
96 changes: 96 additions & 0 deletions notes/raw_chatgpt_responses/cosine_similarity_raw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<exercise>
<description>
---
title: Sentence Similarity
author:
- ChatGPT
- Christopher Schölzel
keywords:
- language: python
- course: Introduction to Python for computational linguists
lang: en-US
solution-size: 11 # measured in lines of code
id: 5111a717-e313-49b5-b95f-8bec5a07e31f
---

# Sentence Similarity

Implement a function `sentence_similarity(sentence1: str, sentence2: str) -> float` in `sentence_similarity.py` which calculates the cosine similarity between two input sentences.

The cosine similarity between two vectors A and B is calculated as:

\[ \text{similarity} = \frac{A \cdot B}{\|A\| \times \|B\|} \]

Where \(A \cdot B\) is the dot product of A and B, and \(\|A\|\) and \(\|B\|\) are the magnitudes of vectors A and B, respectively. For sentences, you'll treat them as Bag-of-Words vectors, where each word is a dimension and the value is the frequency of the word in the sentence.

Example:

```python
similarity = sentence_similarity("I like bananas", "I like apples")
print(similarity) # Output should be approximately 0.7071067811865475
```

You can ignore punctuation and consider words case-insensitively.

> Tip: You can use the `Counter` class from the `collections` module to count word frequencies.
Make sure to save the function in a file called `sentence_similarity.py` so that it can be imported with `from sentence_similarity import sentence_similarity`.

</description>
<unittest>

```python
import unittest
from sentence_similarity import sentence_similarity

class TestSimilarity(unittest.TestCase):

def test_similarity_same_sentence(self):
sentence1 = "I like bananas"
similarity = sentence_similarity(sentence1, sentence1)
self.assertEqual(1.0, similarity)

def test_similarity_different_sentences(self):
sentence1 = "I like bananas"
sentence2 = "I like apples"
similarity = sentence_similarity(sentence1, sentence2)
self.assertAlmostEqual(0.7071067811865475, similarity, places=5)

def test_similarity_different_order(self):
sentence1 = "I like bananas"
sentence2 = "bananas like I"
similarity = sentence_similarity(sentence1, sentence2)
self.assertEqual(1.0, similarity)

if __name__ == '__main__':
unittest.main()
```

</unittest>
<example_solution>

```python
from typing import List
from collections import Counter
import math

def sentence_similarity(sentence1: str, sentence2: str) -> float:
def vectorize(sentence):
words = sentence.lower().split()
word_counts = Counter(words)
return word_counts

vec1 = vectorize(sentence1)
vec2 = vectorize(sentence2)

intersection = set(vec1.keys()) & set(vec2.keys())
dot_product = sum(vec1[word] * vec2[word] for word in intersection)

magnitude1 = math.sqrt(sum(vec1[word] ** 2 for word in vec1))
magnitude2 = math.sqrt(sum(vec2[word] ** 2 for word in vec2))

similarity = dot_product / (magnitude1 * magnitude2)
return similarity
```
</example_solution>
</exercise>
65 changes: 65 additions & 0 deletions notes/raw_chatgpt_responses/is_anagram_raw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<exercise>
<description>
---
title: Anagram Checker
author:
- ChatGPT
- Christopher Schölzel
keywords:
- language: python
- course: Introduction to Python for computational linguists
lang: en-US
solution-size: 10 # measured in lines of code
id: 93853c04-1782-4ed1-8275-1f3f934d635e
---

# Anagram Checker

Create a function called `is_anagram(word1: str, word2: str) -> bool` in `anagram.py` that checks if two input strings are anagrams of each other. An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once. The function should return `True` if the two words are anagrams, and `False` otherwise.

Example:

```python
result = is_anagram("listen", "silent")
print(result) # -> True

result = is_anagram("hello", "world")
print(result) # -> False
```

> Hint: You can use Python's Counter class to count occurrences of characters in each word.
Make sure to save the function in a file called `anagram.py` so that it can be imported with `from anagram import is_anagram`.

</description>
<unittest>

```python
import unittest
from anagram import is_anagram

class TestAnagram(unittest.TestCase):

def test_valid_anagram(self):
self.assertTrue(is_anagram("listen", "silent"))
self.assertTrue(is_anagram("rail safety", "fairy tales"))

def test_invalid_anagram(self):
self.assertFalse(is_anagram("hello", "world"))
self.assertFalse(is_anagram("python", "pythons"))

if __name__ == '__main__':
unittest.main()
```

</unittest>
<example_solution>

```python
from collections import Counter

def is_anagram(word1: str, word2: str) -> bool:
return Counter(word1) == Counter(word2)
```
</example_solution>
</exercise>
95 changes: 95 additions & 0 deletions notes/raw_chatgpt_responses/ngram_raw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<exercise>
<description>
---
title: Ngram Model
author:
- ChatGPT
- Christopher Schölzel
keywords:
- language: python
- course: Introduction to Python for computational linguists
lang: en-US
solution-size: 20 # measured in lines of code
id: 2d9898f0-5e25-40c2-8d7c-f842c01166e1
---

# Ngram Model

Create a class `NgramModel` in `ngram.py` that can generate an ngram model and make predictions based on it. The class should have the following methods:

1. `__init__(self, n: int)` - Initialize the ngram model with the value of `n`, the order of the ngrams.
2. `train(self, text: str)` - Train the model using the provided text. This method should build the ngram model.
3. `predict(self, prefix: str) -> List[str]` - Given a prefix, predict the next word based on the trained ngram model. Return a list of possible predictions sorted by their probabilities.

Example:

```python
model = NgramModel(2)
model.train("The quick brown fox jumps over the lazy dog")
predictions = model.predict("The quick")
print(predictions) # -> ['brown', 'fox']
```

Make sure to save the class in a file called `ngram.py` so that it can be imported with `from ngram import NgramModel`.

</description>
<unittest>

```python
import unittest

from ngram import NgramModel

class TestNgramModel(unittest.TestCase):

def test_ngram_2(self):
model = NgramModel(2)
model.train("The quick brown fox jumps over the lazy dog")
predictions = model.predict("The quick")
self.assertCountEqual(["brown", "fox"], predictions)

def test_ngram_3(self):
model = NgramModel(3)
model.train("The quick brown fox jumps over the lazy dog")
predictions = model.predict("quick brown")
self.assertCountEqual(["fox"], predictions)

def test_ngram_4(self):
model = NgramModel(3)
model.train("The quick brown fox jumps over the lazy dog")
predictions = model.predict("jumps over")
self.assertCountEqual(["the"], predictions)

if __name__ == '__main__':
unittest.main()
```

</unittest>
<example_solution>

```python
from typing import List, Dict
from collections import defaultdict
import random

class NgramModel:
def __init__(self, n: int):
self.n = n
self.ngrams = defaultdict(list)

def train(self, text: str):
words = text.split()
for i in range(len(words) - self.n):
prefix = tuple(words[i:i + self.n - 1])
next_word = words[i + self.n - 1]
self.ngrams[prefix].append(next_word)

def predict(self, prefix: str) -> List[str]:
prefix_words = prefix.split()
prefix = tuple(prefix_words[-self.n + 1:])
possible_next_words = self.ngrams.get(prefix, [])
return sorted(possible_next_words, key=lambda w: self.ngrams[prefix].count(w), reverse=True)

```
</example_solution>
</exercise>
Loading

0 comments on commit 7219675

Please sign in to comment.