Autor Thema: Produktbewertungen: Auswertung und Übersicht  (Gelesen 141911 mal)

Finglan

  • Newbie
  • *
  • Beiträge: 49
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #120 am: 26 Feb 2018, 17:28:50 »
Hab mir das mal gerade angeguckt und gefixt. Fehler war, das self.produkt_ergebnisse nie beschrieben wurde.

#!/usr/bin/python
# coding=utf-8

import urllib.request
import xlsxwriter
from statistics import StatisticsError, mean
from bs4 import BeautifulSoup
from collections import namedtuple, OrderedDict
from operator import attrgetter
from multiprocessing.dummy import Pool as ThreadPool

# Collection of Thread IDs in several categories
Produktthreads = OrderedDict([
    ('Spielhilfen', [
100244 ,
99039 ,
98315 ,
103886

]),
    ('Abenteuer', [
97188 ,
98757 ,
100657 ,
103971
])
])

# maintain anthologies separately
Anthologien = OrderedDict([
                           ('Cthulhu - Ars Mathematica',[
                                            102159, 102160, 102158]),
                           ('Cthulhu - Dreissig',[
                                            101501, 101503, 101504, 101502]),
                           ('Cthulhu - The Final Revelation',[
                                            97284, 97285, 97286, 97287]),
                           ('Cthulhu - Die Goldenen Hände Suc´naaths',[
                                            98758, 98757, 98759]),
                           ('Shadowrun - Licht aus der Asche',[
                                            96028, 96027, 96026])
                           ])

# Add anthologies to collection to avoid duplicates
for Anthologie in Anthologien:
    for threadid in Anthologien[Anthologie]:
        if threadid not in Produktthreads['Abenteuer']:
            Produktthreads['Abenteuer'].append(threadid)

# URL of a thread (%d will be thread_id)
baseurl = "https://www.tanelorn.net/index.php?topic=%d.0"

# Number of parallel threads (should be equal to number of CPU cores)
concurrent_parses = 4


def bbcode(tag, string, value=None):
    """Return a text(string) enclosed by the bbcode tags"""
    if value:
        return'[' + tag + '=' + value + ']' + string + '[/' + tag + ']'
    else:
        return'[' + tag + ']' + string + '[/' + tag + ']'


def bbcodeurl(urlstring, urlname):
    """Return an bbcode url format for given url and description"""
    return bbcode('url', urlname, urlstring)


def bbbold(text):
    """Return the text with a bbcode bold tag"""
    return bbcode(tag='b', string=text)


def bbtt(text):
    """Return the text with a bbcode tt tag"""
    return bbcode(tag='tt', string=text)


class bbtable():

    """creates the frame of a bbcode table"""

    def __init__(self, rows):
        """needs the rows as input for this table"""
        self.elements = rows

    def tablify(self, rows):
        """adds start and end tags for tables"""
        return str('[table]\r\n' + rows + '[/table]')

    def __str__(self):
        """prints table in bbcode format"""
        return(self.tablify(''.join(str(row) for row in self.elements)))


class tablerow(bbtable):

    """creates a bbcode table row with correct tags"""

    def cellify(self, rowfield):
        """encloses cells with correct tags"""
        return str('[td]' + str(rowfield) + '[/td]')

    def rowify(self, cells):
        """encloses rows with the correct tags"""
        return str('[tr]' + str(cells) + '[/tr]\r\n')

    def __str__(self):
        """adds cell and row tags to elements"""
        return(self.rowify(''.join(self.cellify(field) for field in self.elements)))


class tableheaderrow(tablerow):

    """adds a header row"""

    def cellify(self, rowfield):
        return str('[td]' + bbbold(rowfield) + bbtt('   ') + '[/td]')


class ProduktParser():

    def __init__(self, Produktthreads, Produkt = namedtuple('Produkt', 'name id url Stimmen Durchschnitt'), Produkte = [], Anthologien = [], baseurl = baseurl):
        """set base properties: URLs, thread ids, format"""
        self.produkt_ergebnisse = []
        self.anthologie_ergebnisse = []
        self.Produkt = Produkt
        self.Produkte = Produkte
        self.baseurl = baseurl
        self.Produktthreads = Produktthreads
        self.Anthologien = Anthologien
        self.bewertungen = set(
            [item for sublist in self.Produktthreads.values() for item in sublist])
        self.pool = ThreadPool(concurrent_parses)
        self.pool.map(self.getProdukt, self.bewertungen)
        self.getAnthologie()
        self.calculate_average()

    def calculate_average(self):
        for produkt in self.produkt_ergebnisse:
            produkt.calculate_mean()
 

    def getProdukt(self, threadid):
        """collect information for selected thread id"""
        url = self.baseurl % threadid
        page = urllib.request.urlopen(url)
        soup = BeautifulSoup(page.read(), "html.parser")
        Produktname = soup.find('title').string.split('/')[0].strip()
        polls = soup.find('dl', {'class': 'options'})
        options = polls.findAll('dt', {'class': 'middletext'})
        votes = polls.findAll('span', {'class': 'percentage'})       
        ergebnis = dict(zip([[int(s) for s in option.string.replace("(","").split() if s.isdigit()][0] for option in options], [int(vote.string.split(' ')[0]) for vote in votes]))
        einzelvotes = [
            item for sublist in [[k] * v for k, v in ergebnis.items()] for item in sublist]
        try:
            durchschnitt = str(round(mean(einzelvotes), 2))
            stimmen = len(einzelvotes)
        except (ZeroDivisionError, StatisticsError) as e:
            durchschnitt = '0 / No votes yet'
            stimmen = 0
        self.Produkte.append(
            self.Produkt(Produktname, threadid, url, stimmen, durchschnitt))
       
    def getAnthologie(self):
        for Anthologie in self.Anthologien:
            Anthologiedurchschnittagg = 0
            Anthologiestimmen = 0
            for Spielhilfe in self.Produkte:
                if Spielhilfe.id in self.Anthologien[Anthologie]:
                    if  Spielhilfe.Durchschnitt != '0 / No votes yet':
                        Anthologiestimmen += Spielhilfe.Stimmen 
                        Anthologiedurchschnittagg += Spielhilfe.Stimmen * float(Spielhilfe.Durchschnitt)
            if Anthologiestimmen == 0:
                Anthologiedurchschnitt = '0 / No votes yet'
            else:
                Anthologiedurchschnitt = str(round(Anthologiedurchschnittagg/Anthologiestimmen, 2))
                         
            self.Produkte.append(
                self.Produkt(Anthologie, 0, 0, Anthologiestimmen, Anthologiedurchschnitt))

    def get_produkt_ergebnisse(self, produkt_typ):

        result = [produkt for produkt in self.produkt_ergebnisse
                                 if produkt.thread_id in self.Produktthreads[produkt_typ]]
        return enumerate(sorted(result))

    def get_anthologie_ergebnisse(self):
        return enumerate(sorted(self.anthologie_ergebnisse))

    def get_all(self):
        return enumerate(sorted(self.Produkte))
                   

    def generateTable(self, bewertungsthreads):
        """"generate a table for the threads"""
        return bbtable([tableheaderrow(['Platz', 'Bewertung', 'Stimmen', 'Produkt'])]
                       + [tablerow([index + 1, element.Durchschnitt, element.Stimmen, bbcodeurl(element.url, element.name)])
                          for index, element in enumerate(sorted(bewertungsthreads, key=attrgetter('Durchschnitt'), reverse=True))])

    def printProdukte(self):
        """"print the table"""
        for key, value in self.Produktthreads.items():
            print('\r\n' + bbbold(key))
            print(self.generateTable(
                [Spielhilfe for Spielhilfe in self.Produkte if Spielhilfe.id in value]))
           
        print('\r\n' + bbbold("Anthologien"))
        print(self.generateTable(
            [Spielhilfe for Spielhilfe in self.Produkte if Spielhilfe.name in [Anthologie for Anthologie in Anthologien]]))

def generate_xlsx(produkte):
    # Create a workbook and add a worksheet.
    workbook = xlsxwriter.Workbook('Bewertungen.xlsx')
    worksheet = workbook.add_worksheet()

    # Start from the first cell. Rows and columns are zero indexed.
    row = 0
    col = 0

    # Iterate over the data and write it out row by row.
    for index, element in produkte:
        worksheet.write(row, col, index + 1)
        worksheet.write(row, col + 1, element.Durchschnitt)
        worksheet.write(row, col + 2, element.Stimmen)
        worksheet.write(row, col + 3, element.url)
        worksheet.write(row, col + 4, element.name)
        row += 1

    workbook.close()

if __name__ == '__main__':
    TanelornParser = ProduktParser(Produktthreads=Produktthreads, Anthologien=Anthologien)


    generate_xlsx(TanelornParser.get_all())

Ich glaube man könnte auch noch ein bisschen im Skript aufräumen ;)

Thallion

  • Moderator
  • Sr. Member
  • *****
  • Beiträge: 250
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #121 am: 26 Feb 2018, 18:20:31 »
Herzlichen Dank!

Thallion

  • Moderator
  • Sr. Member
  • *****
  • Beiträge: 250
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #122 am: 28 Feb 2018, 09:47:32 »
Ich habe die Bayes-Methode und "Enthalten in" als separate Spalte, die Heldengrade und das Erscheinungs-Jahr als sortierbare Zahl hinzugefügt:

https://dsanews.de/abenteuerbewertungen-splittermond/

https://dsanews.de/spielhilfenbewertungen-splittermond/

SeldomFound

  • Beta-Tester
  • Hero Member
  • ***
  • Beiträge: 10.283
  • Wohin auch die Reise geht, ich bin da
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #123 am: 28 Feb 2018, 10:09:56 »
Vielen Dank für deine tolle Arbeit!

Gesendet von meinem GT-I9301I mit Tapatalk

Patience is a virtue, possess it if you can
Seldom found in woman
Never found in man

Thallion

  • Moderator
  • Sr. Member
  • *****
  • Beiträge: 250
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #124 am: 06 Mär 2018, 13:12:53 »
Die Rollenspiel-Bewertungen bekommen zusätzlich zu DSANews eine eigene Domain. Danke an Zorni und DSANews!

Was meint ihr wie sollte diese heißen?

www.Rollenspiel-Bewertungen.de
www.PenandPaper-Bewertungen.de

Weitere Vorschläge?
« Letzte Änderung: 06 Mär 2018, 13:31:39 von Thallion »

maggus

  • Beta-Tester
  • Hero Member
  • ***
  • Beiträge: 2.080
  • Zeigefingerzeiger
    • Profil anzeigen
    • maggus bei Facebook
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #125 am: 06 Mär 2018, 17:48:33 »
"Rollenspiel-Bewertungen" wäre mir zu allgemein, die meisten Menschen verknüfen damit anderes. "Pen&Paper" ist da viel eindeutiger (so heißt auch der Wikipedia-Artikel Pen-&-Paper-Rollenspiel).

Was mir noch einfällt: "Tischrollenspiel-Bewertungen", oder "RPG-Bewertungen"
"Befreien Sie das Unreich!"

4 Port USB Hub

  • Hero Member
  • *****
  • Beiträge: 1.047
  • Jetzt mit USB 3.0 Ports
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #126 am: 06 Mär 2018, 17:55:10 »
RPGDB
Für Fetzenstein! Nieder mit Knax!

Thallion

  • Moderator
  • Sr. Member
  • *****
  • Beiträge: 250
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #127 am: 07 Mär 2018, 08:22:11 »

Thallion

  • Moderator
  • Sr. Member
  • *****
  • Beiträge: 250
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #128 am: 08 Mär 2018, 13:48:05 »
Bitte nochmal an der Stichwahl teilnehmen.

https://www.tanelorn.net/index.php/topic,106081.0.html

Thallion

  • Moderator
  • Sr. Member
  • *****
  • Beiträge: 250
    • Profil anzeigen
Style Theme Bewertungsportal?
« Antwort #129 am: 11 Mär 2018, 09:44:02 »
Habt ihr Wünsche, Vorschläge & Tipps für ein Style Theme des Bewertungsportals?

https://de.wordpress.org/themes/
https://themeforest.net/category/wordpress

Das Aktuelle (Wellington) ist schlicht und funktional. Kann natürlich auch dabei bleiben.

https://rollenspiel-bewertungen.de/
« Letzte Änderung: 11 Mär 2018, 09:59:02 von Thallion »

Thallion

  • Moderator
  • Sr. Member
  • *****
  • Beiträge: 250
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #130 am: 12 Mär 2018, 14:30:03 »
Hier findet ihr den momentanen Stand der Seite und hoffe auf Feedback von euch https://rollenspiel-bewertungen.de/

Jeong Jeong

  • Korsaren
  • Hero Member
  • *
  • Beiträge: 3.782
  • Autorin und Cosplayerin
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #131 am: 12 Mär 2018, 17:11:04 »
Ein FAQ wäre noch super, wo vor allem die Bayes-Bewertung erklärt werden könnte.

Thallion

  • Moderator
  • Sr. Member
  • *****
  • Beiträge: 250
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #132 am: 18 Mär 2018, 08:46:11 »
Ein FAQ wäre noch super, wo vor allem die Bayes-Bewertung erklärt werden könnte.
Kann mir denn jemand eine allgemein verständliche Erklärung dafür schreiben?
Dann stelle ich das in ein FAQ. Ich hab zu der Bayes-Methodik keinen richtigen Draht.

Ich würde gerne Roman-Bewertungen starten, ist das ok für euch?

Jeong Jeong

  • Korsaren
  • Hero Member
  • *
  • Beiträge: 3.782
  • Autorin und Cosplayerin
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #133 am: 18 Mär 2018, 10:23:04 »
Bayes-Bewertung:

"Die Bayes-Bewertung basiert auf der normalen Durchschnittsbewertung, die leicht angepasst wird. Denn um zu verhindern, dass Produkte mit relativ wenigen sehr guten Bewertungen an der Spitze der Übersichten stehen, werden bei der Bayes-Bewertung 50 Bewertungen mit der Wertung 3,5 in den Durchschnittswert mit eingerechnet. Dadurch wird die Durchschnittsbewertung in Richtung der Mitte der von 1-6 reichenden Bewertungsskala gezogen. Die Durchschnittsbewertungen von Produkten mit vielen Stimmen werden dabei wenig verändert, während die von Produkten mit wenig Bewertungen stark in Richtung 3,5 gehen. Diese Methode nennt man Bayseian Average, benannt nach dem Mathematiker Thomas Bayes."

Kursiv die Punkte, die bei dir glaube ich anders sind als aktuell noch in der Splitterwiki.

Thallion

  • Moderator
  • Sr. Member
  • *****
  • Beiträge: 250
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #134 am: 20 Mär 2018, 15:44:37 »
Hm schade. Wollte gerade ein Update hoch laden, aber bei nur 11 Stimmen mehr, lohnt das irgendwie nicht  :(