input: from typing import List
  
  def sentiment_analysis(reviews: List[str]) -> str:
      """ Perform sentiment analysis on product reviews using natural language processing techniques.
      This function:
      1. Tokenizes the reviews.
      2. Removes stopwords.
      3. Normalizes the words.
      4. Generates features using CountVectorizer.
      5. Splits the data into training and test sets.
      6. Trains a Naive Bayes classifier.
      7. Predicts sentiments on the test set.
      8. Generates a classification report.
      
      >>> sentiment_analysis(['This product is amazing!', 'I hate it.'])
      '              precision    recall  f1-score   support\n\n     neg       1.00      0.50      0.67         2\n     pos       0.50      1.00      0.67         1\n\naccuracy                           0.67         3\n   macro avg       0.75      0.75      0.67         3\nweighted avg       0.83      0.67      0.67         3\n'
      """
output:     from sklearn.feature_extraction.text import CountVectorizer
      from sklearn.model_selection import train_test_split
      from sklearn.naive_bayes import MultinomialNB
      from sklearn.metrics import classification_report
      from nltk.corpus import stopwords
      from nltk.tokenize import word_tokenize
      from nltk.stem import WordNetLemmatizer
      import string
  
      # Tokenize the reviews
      tokenized_reviews = [word_tokenize(review.lower()) for review in reviews]
  
      # Remove stopwords and punctuation
      stop_words = set(stopwords.words('english'))
      filtered_reviews = [[word for word in review if word.isalnum() and word not in stop_words] for review in tokenized_reviews]
  
      # Normalize the words
      lemmatizer = WordNetLemmatizer()
      normalized_reviews = [[lemmatizer.lemmatize(word) for word in review] for review in filtered_reviews]
  
      # Flatten the list of lists
      flat_reviews = [' '.join(review) for review in normalized_reviews]
  
      # Generate features using CountVectorizer
      vectorizer = CountVectorizer()
      X = vectorizer.fit_transform(flat_reviews)
  
      # Create labels based on the sentiment of the reviews
      y = ['pos' if '!' in review else 'neg' for review in reviews]
  
      # Split the data into training and test sets
      X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=42)
  
      # Train a Naive Bayes classifier
      classifier = MultinomialNB()
      classifier.fit(X_train, y_train)
  
      # Predict sentiments on the test set
      y_pred = classifier.predict(X_test)
  
      # Generate a classification report
      report = classification_report(y_test, y_pred, output_dict=False)
  
      return report