from collections import Counter
import re
import requests
import bs4
import nltk
from nltk.corpus import stopwords


def main():
    # Używa webscrappingu do pobrania tekstu.
    url = 'http://www.analytictech.com/mb021/mlk.htm'
    page = requests.get(url)
    page.raise_for_status()
    soup = bs4.BeautifulSoup(page.text, 'html.parser')
    p_elems = [element.text for element in soup.find_all('p')]

    # Łączy elementy i wstawia między nie spacje.
    speech = ' '.join(p_elems) 

    # Poprawia literówki, usuwa zbędne spacje, cyfry 
    # i znaki interpunkcyjne.
    speech = speech.replace(')mowing', 'knowing')
    speech = re.sub('\s+', ' ', speech)
    speech_edit = re.sub('[^a-zA-Z]', ' ', speech)
    speech_edit = re.sub('\s+', ' ', speech_edit)

    # Pobiera instrukcje od użytkownika.
    while True:
        max_words = input("Wprowadź maksymalną liczbę słów w zdaniu: ")
        num_sents = input("Wprowadź liczbę zdań w streszczeniu: ")
        if max_words.isdigit() and num_sents.isdigit():
            break
        else:
            print("\nWprowadzane wartości muszą być liczbami całkowitymi.\n")

    # Wywołuje funkcje generujące punktację zdań.
    speech_edit_no_stop = remove_stop_words(speech_edit)
    word_freq = get_word_freq(speech_edit_no_stop)
    sent_scores = score_sentences(speech, word_freq, max_words)

    # Drukuje najwyżej ocenione zdania.
    counts = Counter(sent_scores)
    summary = counts.most_common(int(num_sents))
    print("\nSTRESZCZENIE: ")
    for i in summary:
        print(i[0])


def remove_stop_words(speech_edit):
    """Zwraca nowy ciąg znaków z usuniętymi słowami nieindeksowanymi."""
    stop_words = set(stopwords.words('english'))
    speech_edit_no_stop = ''
    for word in nltk.word_tokenize(speech_edit):
        if word.lower() not in stop_words:
            speech_edit_no_stop += word + ' '
    return speech_edit_no_stop


def get_word_freq(speech_edit_no_stop):
    """Zwraca słownik częstości występowania wyrazów w ciągu znaków."""
    word_freq = nltk.FreqDist(nltk.word_tokenize(speech_edit_no_stop
                                                 .lower()))
    return word_freq


def score_sentences(speech, word_freq, max_words):
    """
    Zwraca słownik z punktacją zdań dokonaną na podstawie
    częstości występowania słów.
    """
    sent_scores = dict()
    sentences = nltk.sent_tokenize(speech)
    for sent in sentences:
        sent_scores[sent] = 0
        words = nltk.word_tokenize(sent.lower())
        sent_word_count = len(words)
        if sent_word_count <= int(max_words):
            for word in words:
                if word in word_freq.keys():
                    sent_scores[sent] += word_freq[word]
            sent_scores[sent] = sent_scores[sent] / sent_word_count
    return sent_scores


if __name__ == '__main__':
    main()
