[SOLVED] Jedno słowo na jeden wiersz + chmura słów
[SOLVED] Jedno słowo na jeden wiersz + chmura słów
Witam
Nie jest to jeszcze realny problem, a przygotowanie do zadania.
Muszę scharakteryzować słownictwo użyte z miesięczniku (6 edycji), który ma ~ 150 stron. Pomyślałem, że najlepiej byłoby zeskanować programem OCR co dziesiątą stronę każdego numeru. W ten sposób stworzyłbym bazę wyrażeń. Raczej nie ma co liczyć na integrację z OO.o, ale też nie powinno być problemu z importem de facto czystego tekstu zapisanego w Wordzie czy Excelu.
Z sześciu wydań będzie to 90 stron tekstu z porozrzucanymi i pomieszanymi słowami w całych zdaniach. Problem polega na tym, że - dla zwiększenia czytelności - należałoby porozdzielać te słowa, tak by na jeden wiersz/komórkę (Writer/Calc - preferuję ten drugi) przypadało jedno słowo.
I banalny przykładzik. Zdanie "Ala ma kota, a kot ma pchły". Zdanie to powinno zostać podzielone na części:
-Ala
-ma
-kota
-a
-kot
-ma
-pchły
Następnie taki zbiór będę musiał alfabetycznie posortować, ale to już jest czynnością banalną.
Proszę o pomoc.
Nie jest to jeszcze realny problem, a przygotowanie do zadania.
Muszę scharakteryzować słownictwo użyte z miesięczniku (6 edycji), który ma ~ 150 stron. Pomyślałem, że najlepiej byłoby zeskanować programem OCR co dziesiątą stronę każdego numeru. W ten sposób stworzyłbym bazę wyrażeń. Raczej nie ma co liczyć na integrację z OO.o, ale też nie powinno być problemu z importem de facto czystego tekstu zapisanego w Wordzie czy Excelu.
Z sześciu wydań będzie to 90 stron tekstu z porozrzucanymi i pomieszanymi słowami w całych zdaniach. Problem polega na tym, że - dla zwiększenia czytelności - należałoby porozdzielać te słowa, tak by na jeden wiersz/komórkę (Writer/Calc - preferuję ten drugi) przypadało jedno słowo.
I banalny przykładzik. Zdanie "Ala ma kota, a kot ma pchły". Zdanie to powinno zostać podzielone na części:
-Ala
-ma
-kota
-a
-kot
-ma
-pchły
Następnie taki zbiór będę musiał alfabetycznie posortować, ale to już jest czynnością banalną.
Proszę o pomoc.
Standardowa diagnostyka rozwiązuje 90% problemów typu "wcześniej działało, ale już nie działa".
Przepis na LibreOffice
Uzyskałeś pomoc? Poinformuj innych o sprawdzonym rozwiązaniu i podziękuj. Dodaj [SOLVED] w tytule.
Przepis na LibreOffice
Uzyskałeś pomoc? Poinformuj innych o sprawdzonym rozwiązaniu i podziękuj. Dodaj [SOLVED] w tytule.
Re: Jedno słowo na jeden wiersz/jedną komórkę
Filtrem go, filtrem.
1. wszystkie znaki przestankowe na spacje
2. wszystkie grupy spacji na entery
3. ujednolicić pisownię wielkimi/małymi literami (tylko małe?)
4. sort
Razem, przy użyciu filtrów uniksowych, zrobisz to mniej więcej tak:Pisane z palca bez dogłębnego sprawdzania, więc mogą być nieścisłości.
Wynik możesz sobie wczytać do calca.
Jest to potężne narzędzie dla kogoś, kto się nie boi konsoli i formatu tekstowego. W tym przypadku zalecanie rozwiązań wewnątrz pakietu biurowego jest tylko półśrodkiem -- do podobnych prac nic lepszego od filtrów nie wymyślono od 30 lat.
Punkty 1. i 2. da się połączyć zastępując grupy znaków przestankowych i/lub spacji pojedynczym enterem.
Btw: konstrukcja
sort -i | uniq -c | sort -n
zlicza Ci powtórzenia z krotnościami i sortuje wg częstości. Ale wcześniej zapewne trzeba sobie poradzić z fleksją.
1. wszystkie znaki przestankowe na spacje
2. wszystkie grupy spacji na entery
3. ujednolicić pisownię wielkimi/małymi literami (tylko małe?)
4. sort
Razem, przy użyciu filtrów uniksowych, zrobisz to mniej więcej tak:
Kod: Zaznacz cały
cat tekst.txt | tr "[\.,;:]" " " | sed -e "s/ */\n/g" | tr "A-ZĄĆĘŁŃÓŚŹŻ" "a-ząćęłńóśźż" | sort -i > wynik.txt
Wynik możesz sobie wczytać do calca.
Jest to potężne narzędzie dla kogoś, kto się nie boi konsoli i formatu tekstowego. W tym przypadku zalecanie rozwiązań wewnątrz pakietu biurowego jest tylko półśrodkiem -- do podobnych prac nic lepszego od filtrów nie wymyślono od 30 lat.
Punkty 1. i 2. da się połączyć zastępując grupy znaków przestankowych i/lub spacji pojedynczym enterem.
Btw: konstrukcja
sort -i | uniq -c | sort -n
zlicza Ci powtórzenia z krotnościami i sortuje wg częstości. Ale wcześniej zapewne trzeba sobie poradzić z fleksją.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Re: Jedno słowo na jeden wiersz/jedną komórkę
Dziękuję za skuteczny filtr.
Zeskanowałem około 160 stron treści, którą zapisałem jako czysty tekst (plik tekst.txt). Plik ten potraktowałem polecanym filtrem, po czym pousuwałem spacje, kwadraty, znaki potęg i inne dziwne symbole (było tego prawie 5 tysięcy wierszy). Potem musiałem sprowadzić wyrazy do ich podstawowej formy. Skorzystałem tutaj z programu Morfologik-stemming 1.4.0. Akurat program jest nieskomplikowany i wszystko podpowiada. Wystarczyło wklepać komendę i wynik był po paru sekundach.
Zawartość pliku wynik2.txt prezentuje się bardzo ładnie.
Teraz pozostało wyodrębnić tylko formę podstawową:
I zliczyć powtórzenia i częstość występowania:
Teraz kombinuję jak zrobić z tego "chmurę tagów".
Zeskanowałem około 160 stron treści, którą zapisałem jako czysty tekst (plik tekst.txt). Plik ten potraktowałem polecanym filtrem, po czym pousuwałem spacje, kwadraty, znaki potęg i inne dziwne symbole (było tego prawie 5 tysięcy wierszy). Potem musiałem sprowadzić wyrazy do ich podstawowej formy. Skorzystałem tutaj z programu Morfologik-stemming 1.4.0. Akurat program jest nieskomplikowany i wszystko podpowiada. Wystarczyło wklepać komendę i wynik był po paru sekundach.
Kod: Zaznacz cały
quest2@quest:~/Downloads/morfologik-stemming-1.4.0$ java -jar morfologik-stemming-1.4.0.jar plstem -i wynik.txt -ie UTF-8 -o wynik2.txt
Input encoding: UTF-8
Output encoding: UTF-8
Processed 57,771 words in 0.785 seconds (73594 words per second).
Jak widać w zacytowanym tekście, forma podstawowa mieści się w drugiej kolumnie (mamy odmienione słowo, jego podstawową formę i informacje o wyrazie - czy to rzeczownik/czasownik/..., czy jest w liczbie mnogiej czy pojedynczej itd.)abolicją abolicja subst:sg:inst:f
abolicji abolicja subst:pl:gen:f+subst:sg:gen.dat.loc:f
abonament abonament subst:sg:nom.acc:m3
abonament abonament subst:sg:nom.acc:m3
abonamentu abonament subst:sg:gen:m3
abonenci abonent subst:pl:nom.voc:m1
Teraz pozostało wyodrębnić tylko formę podstawową:
Kod: Zaznacz cały
awk -F'\t' '{print $2}' wynik2.txt > wynik3.txt
Kod: Zaznacz cały
cat wynik3.txt | tr "[\.,;:]" " " | sed -e "s/ */\n/g" | tr "A-ZĄĆĘŁŃÓŚŹŻ" "a-ząćęłńóśźż" | sort -i | uniq -c | sort -n > wynik4.txt
Standardowa diagnostyka rozwiązuje 90% problemów typu "wcześniej działało, ale już nie działa".
Przepis na LibreOffice
Uzyskałeś pomoc? Poinformuj innych o sprawdzonym rozwiązaniu i podziękuj. Dodaj [SOLVED] w tytule.
Przepis na LibreOffice
Uzyskałeś pomoc? Poinformuj innych o sprawdzonym rozwiązaniu i podziękuj. Dodaj [SOLVED] w tytule.
Re: Jedno słowo na jeden wiersz/jedną komórkę
Cześć,
ja bym zaproponował:
założyć ile rozróżnialnych kategorii stylów ma być w chmurze, i jakie mają być ich wartości progowe (zapewne w skali logarytmicznej?)
zastępować pary (krotność, słowo) odwołaniami (piszę w postaci xhtml, ale możesz chcieć xlinka albo co) typu <a class="klasa dla tej krotności" href="cokolwiek chcesz">słowo<a>
najważniejsze to
* umieć wyznaczyć nazwę klasy dla znanego numeru. sed jest do tego za cieńki, chyba że operujesz logarytmem dziesiętnym, wtedy długość numeru wyznacza klasę i od biedy sobie poradzisz. Ale w awk masz liczby, trzeba se tylko funkcję napisać
* mieć do czego odsyłać.
ja bym zaproponował:
założyć ile rozróżnialnych kategorii stylów ma być w chmurze, i jakie mają być ich wartości progowe (zapewne w skali logarytmicznej?)
zastępować pary (krotność, słowo) odwołaniami (piszę w postaci xhtml, ale możesz chcieć xlinka albo co) typu <a class="klasa dla tej krotności" href="cokolwiek chcesz">słowo<a>
najważniejsze to
* umieć wyznaczyć nazwę klasy dla znanego numeru. sed jest do tego za cieńki, chyba że operujesz logarytmem dziesiętnym, wtedy długość numeru wyznacza klasę i od biedy sobie poradzisz. Ale w awk masz liczby, trzeba se tylko funkcję napisać
* mieć do czego odsyłać.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Re: [SOLVED] Jedno słowo na jeden wiersz/jedną komórkę
Problem ten rozwiązałem w inny sposób. Plikowi wynik4.txt zmieniłem rozszerzenie na wynik4.csv i zaimportowałem do Calca. Przed zatwierdzeniem importu tekstu, należy zaznaczyć pole wyboru Scal separatory (Merge delimiters) w części Opcje separatora (Separator options). Potem można kliknąć w przycisk OK.
Jeśli po imporcie danych, pierwsza kolumna będzie pusta, po prostu ją usuwamy. Robimy tak, by w kolumnie "A" widniała ilość powtórzeń danego słowa, a w kolumnie "B" dane słowo (patrz: zdjęcie kolumny.png).
Samą chmurę wygenerowałem makrem, ale o tym za chwilę.
Posiadam procesor Pentium 4 3,2 Ghz. Próba "wychmurzenia" 11 tysięcy słów skończyła się zamrożeniem całego systemu i resetem komputera. Podobno na dwurdzeniowym procesorze 1,6 Ghz działa bez problemów.
Aby sobie z tym poradzić, musiałem nadać OO.o wyższy priorytet.
I teraz przechodzimy do głównej części. Dodajemy makro, które następnie wykonujemy.
Wyskoczy okno z zapytaniem:
* Wprowadź indeks pierwszego wiersza - wpisujemy numer wiersza, od którego zaczynają się nasze dane, czyli wpisujemy 1.
* Wprowadź indeks ostatniego wiersza - analogicznie. Ja wpisałem 11279, bo tyle miałem.
* Minimalny rozmiar czcionki - 8 punktów.
* Maksymalny rozmiar czcionki - 30 punktów.
* Pokazywać ilości wystąpień obok wyrazów? - TAK/NIE.
Otworzy się Writer, w którym będzie się generować chmura słów (patrz: zdjęcie chmura słów.png).
Jeśli po imporcie danych, pierwsza kolumna będzie pusta, po prostu ją usuwamy. Robimy tak, by w kolumnie "A" widniała ilość powtórzeń danego słowa, a w kolumnie "B" dane słowo (patrz: zdjęcie kolumny.png).
Samą chmurę wygenerowałem makrem, ale o tym za chwilę.
Posiadam procesor Pentium 4 3,2 Ghz. Próba "wychmurzenia" 11 tysięcy słów skończyła się zamrożeniem całego systemu i resetem komputera. Podobno na dwurdzeniowym procesorze 1,6 Ghz działa bez problemów.
Aby sobie z tym poradzić, musiałem nadać OO.o wyższy priorytet.
Kod: Zaznacz cały
quest2@quest:~$ ps ax
2287 ? Sl 0:04 /opt/ooo-dev3/program/soffice.bin
Kod: Zaznacz cały
quest2@quest:~$ renice +18 2287
2287: old priority 0, new priority 18
Kod: Zaznacz cały
REM ***** BASIC *****
' Copyright (c) 2010, Paweł Smoliński
' All rights reserved.
' Redistribution and use in source and binary forms, with or without
' modification, are permitted provided that the following conditions are
' met:
' * Redistributions of source code must retain the above copyright
' notice, this list of conditions and the following disclaimer.
' * Redistributions in binary form must reproduce the above copyright
' notice, this list of conditions and the following disclaimer in the
' documentation and/or other materials provided with the distribution.
' * Neither the name of the Paweł Smoliński nor the names of its
' contributors may be used to endorse or promote products derived from
' this software without specific prior written permission.
'
' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
' "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
' TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
' PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
' CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
' EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
' PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
' OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
' WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
' OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
' ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
' Utworzenie "chmury tagów" na podstawie danych pobranych z arkusza kalkulacyjnego:
' - z kolumny A ilości wystąpień danego wyrazu
' - z kolumny B same wyrazny
' - dane pobierane są z 1 arkusza, jeżeli mają być pobierane z innego należy odpowiednio zmodyfikować kod
' UWAGA! Z uwagi na to, iż kod ten pisany był pod konkretne rozwiązanie, posiada on tylko prosty mechanizm
' walidacji i oczekuje, iż użytkownik wprowadzi poprawne zakresy danych
Sub Main
Dim InputDoc as Object 'Dokument Calc'a
Dim Sheet as Object 'Pojedynczy arkusz
Dim Cell as Object 'Pojedyncza komórka w arkuszu
Dim ResultDoc as Object 'Wynikowy dokument tekstowy (Writer)
Dim TxtCursor as Object 'Kursor w dokumencie tekstowym
Dim Dummy() 'Pusta funkcja
Dim MinCol as Integer 'Minimalny indeks kolumny brany pod uwagę(dla A1=1, A3=3 itp.)
Dim MaxCol as Integer 'Maksymalny indeks kolumny brany pod uwagę
Dim I as Integer 'Zmienna pomocnicza
Dim C as Integer ' -"-
Dim W as String ' -"-
Dim MinHeight as Integer 'Minimalna wielkość czcionki, jaka zostanie użyta
Dim MaxHeight as Integer 'Maksymalna wielkość czcionki, jaka zostanie użyta
Dim HeightDiff as Integer 'Różnica w wielkości czcionki
Dim CurrHeight as Single 'Zmienna pomocnicza - wysokość bieżącego wyrazu
Dim MinCount as Integer 'Minimalna liczba wystąpień w podanym zestawie
Dim MaxCount as Integer 'Maksymalna liczba wystąpień w podanym zestawie
Dim CountDiff as Integer 'Różnica w liczbie wystąpień
Dim Cells as Object 'Zmienna pomocnicza - zbiór komórek opisujących liczbę wystąpień
Dim SpaceHeight as Integer 'Wysokość czcionki używanej przy wstawianiu spacji
Dim AddNumbers as Integer 'Informacja czy pokazywać obok wyrazów ilości wystąpień
SpaceHeight = 12 ' <=- Jeżeli czcionka dla spacji ma mieć inną wysokość, zmień tą wartość
' Wprowadzamy zakres wierszy, jakie będą brane pod uwagę
MinCol = InputBox("Wprowadź indeks pierwszego wiersza")
MaxCol = InputBox("Wprowadź indeks ostatniego wiersza")
' Prosta walidacja
If (MinCol < 1 or MaxCol < 1 or MinCol >= MaxCol) Then
MsgBox("Podano nieprawidłowe indeksy wierszy")
Exit Sub
End If
' Wprowadzamy graniczne wielkości czcionek
MinHeight = InputBox("Wprowadź minimalny rozmiar czcionki")
MaxHeight = InputBox("Wprowadź maksymalny rozmiar czcionki")
' Prosta walidacja
If (MinHeight < 1 or MaxHeight < 1 or MinHeight >= MaxHeight) Then
MsgBox("Podano nieprawidłowe wielkości czcionek")
Exit Sub
End If
' Pytanie o to czy pokazywać ilości wystąpień
AddNumbers = MsgBox("Pokazywać ilości wystąpień obok wyrazów?", MB_YESNO + MB_ICONQUESTION)
' Obliczamy Roznice wielkości czcionek
HeightDiff = MaxHeight - MinHeight
' Pobieramy instancję obiektu dokumentu oraz arkuszu
InputDoc = ThisComponent
Sheet = InputDoc.Sheets(0) ' <=- Tutaj dokonaj zmiany, jeżeli chesz operować na innym niż pierwszy arkusz
' Obliczamy maksymalną oraz minimalną liczbę wystąpień
Cells = Sheet.getCellRangeByName("A" + MinCol + ":A" + MaxCol)
MinCount = Cells.computeFunction(com.sun.star.sheet.GeneralFunction.MIN)
MaxCount = Cells.computeFunction(com.sun.star.sheet.GeneralFunction.MAX)
CountDiff = MaxCount - MinCount
If (CountDiff = 0) Then
CountDiff = 1
End If
'Tworzymy instancję nowego dokumentu tekstowego oraz kursora w tym dokumencie
ResultDoc = StarDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, Dummy())
TxtCursor = ResultDoc.Text.createTextCursor()
'Lecimy pokolei po wszystkich kolumnach
For I = MinCol To MaxCol
' Liczba wystąpień (C) oraz danych wyraz (W)
C = Sheet.getCellRangeByName("A" + I).Value
W = Sheet.getCellRangeByName("B" + I).String
If(AddNumbers = IDYES) Then
W = W + "(" + C + ")"
End If
' Obliczamy wysokość czcionki dla danego wyrazu i wstawiamy go do dokumentu
CurrHeight = MinHeight + HeightDiff * (C - MinCount)/CountDiff
TxtCursor.charHeight = CurrHeight
TxtCursor.String = W
TxtCursor.gotoEndOfParagraph(True)
' Wstawiamy spację
TxtCursor.charHeight = SpaceHeight
txtCursor.String = " "
TxtCursor.gotoEndOfParagraph(True)
Next I
End Sub
* Wprowadź indeks pierwszego wiersza - wpisujemy numer wiersza, od którego zaczynają się nasze dane, czyli wpisujemy 1.
* Wprowadź indeks ostatniego wiersza - analogicznie. Ja wpisałem 11279, bo tyle miałem.
* Minimalny rozmiar czcionki - 8 punktów.
* Maksymalny rozmiar czcionki - 30 punktów.
* Pokazywać ilości wystąpień obok wyrazów? - TAK/NIE.
Otworzy się Writer, w którym będzie się generować chmura słów (patrz: zdjęcie chmura słów.png).
Standardowa diagnostyka rozwiązuje 90% problemów typu "wcześniej działało, ale już nie działa".
Przepis na LibreOffice
Uzyskałeś pomoc? Poinformuj innych o sprawdzonym rozwiązaniu i podziękuj. Dodaj [SOLVED] w tytule.
Przepis na LibreOffice
Uzyskałeś pomoc? Poinformuj innych o sprawdzonym rozwiązaniu i podziękuj. Dodaj [SOLVED] w tytule.
Re: [SOLVED] Jedno słowo na jeden wiersz + chmura słów
Grunt, żeby było skutecznie, i żeby się nie zapracować.
Czytam sobie wyniki: i jak tu zgadnąć, co to było za czasopismo?
Czytam sobie wyniki: i jak tu zgadnąć, co to było za czasopismo?
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Re: [SOLVED] Jedno słowo na jeden wiersz + chmura słów
Pismo dla pań, "Caludia" wydawnictwa G+J. Z pojedynczych słówek naprawdę trudno coś wywnioskować jeśli nie jest się w temacie. W przyszłości trzeba będzie pomyśleć nad zdaniami, ale to już robota dla skanera OCR I Morfologika.
Standardowa diagnostyka rozwiązuje 90% problemów typu "wcześniej działało, ale już nie działa".
Przepis na LibreOffice
Uzyskałeś pomoc? Poinformuj innych o sprawdzonym rozwiązaniu i podziękuj. Dodaj [SOLVED] w tytule.
Przepis na LibreOffice
Uzyskałeś pomoc? Poinformuj innych o sprawdzonym rozwiązaniu i podziękuj. Dodaj [SOLVED] w tytule.
Re: [SOLVED] Jedno słowo na jeden wiersz + chmura słów
Że dla pań, zgadnąć nietrudno. Ot, pomyślałem nieco wczorajszo: Kobieta i Życie.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)