Fórum Ubuntu CZ/SK

Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: YaD 09 Srpna 2011, 21:44:34

Název: Regulárny výraz (Python) - chyba pri kompilácií [vyřešeno]
Přispěvatel: YaD 09 Srpna 2011, 21:44:34
Regulárny výraz sa má používať na zachytávanie a spracovávanie takýchto vstupov:
(x^2+5y)^2
(1*x+2y)**4
a pod.

Analýza binomickej vety. Jedná sa o úpravu kódu z http://forum.ubuntu.cz/index.php/topic,57077.0.html .

Kód: [Vybrat]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re

pattern = re.compile(r'''
^ # začiatok reťazcu
\( # číselné vyjadrenie je v zátvorke
( # nasledujúci blok zachytávame - jednotlivé vyjadrenie čísla

( # zachytávame číslo, ktoré násobí vyjadrenie
[-+]? # predpokladáme, že prvý znak bude znamienko, ale nemusí byť
\d* # ľubovolný číselný výraz, ktorý "násobí" hodnotu výrazu
)? # nevyžadujeme ho povinne - násobenie

( # zachytávame jednotlivé premenné
([a-z]) # nejaké alfabetické vyjadrenie výrazu (písmeno), ktorý zachytávame
(?:^|**) # ľubovolný "umocňovateľ"
(\d*) # mocniteľ
)+ # je striktne vyžadovaný

) # blok je u konca
{2} # vyžadujeme ho dvakrát
\) # koniec číselného vyjadrenia

(?:^|**) # mocniteľ...
(\d+) # ľubovolná mocnina zátvorky
$ # koniec reťazcu
''', re.VERBOSE)

print(pattern.search(input()).groups())

Neviem kde je chyba, keďže hláška pri kompilácii mi veľa nepovie, keďže do regulárnych výrazov dobre nevidím:
Kód: [Vybrat]
$ python3 expr.py
Traceback (most recent call last):
  File "expr.py", line 29, in <module>
    ''', re.VERBOSE)
  File "/usr/lib/python3.1/re.py", line 205, in compile
    return _compile(pattern, flags)
  File "/usr/lib/python3.1/re.py", line 273, in _compile
    p = sre_compile.compile(pattern, flags)
  File "/usr/lib/python3.1/sre_compile.py", line 491, in compile
    p = sre_parse.parse(p, flags)
  File "/usr/lib/python3.1/sre_parse.py", line 692, in parse
    p = _parse_sub(source, pattern, 0)
  File "/usr/lib/python3.1/sre_parse.py", line 315, in _parse_sub
    itemsappend(_parse(source, state))
  File "/usr/lib/python3.1/sre_parse.py", line 640, in _parse
    p = _parse_sub(source, state)
  File "/usr/lib/python3.1/sre_parse.py", line 315, in _parse_sub
    itemsappend(_parse(source, state))
  File "/usr/lib/python3.1/sre_parse.py", line 640, in _parse
    p = _parse_sub(source, state)
  File "/usr/lib/python3.1/sre_parse.py", line 315, in _parse_sub
    itemsappend(_parse(source, state))
  File "/usr/lib/python3.1/sre_parse.py", line 640, in _parse
    p = _parse_sub(source, state)
  File "/usr/lib/python3.1/sre_parse.py", line 315, in _parse_sub
    itemsappend(_parse(source, state))
  File "/usr/lib/python3.1/sre_parse.py", line 520, in _parse
    raise error("nothing to repeat")
sre_constants.error: nothing to repeat

Ďakujem za akúkoľvek pomoc.
Název: Re: Regulárny výraz (Python) - chyba pri kompilácií
Přispěvatel: starenka 09 Srpna 2011, 22:04:18
btw je to tim ze nemas escapovany * - coz je meta znak, opravil sem ti to, jen to nic nenajde, takze mas ten regular spatne

Kód: [Vybrat]
(django13)starenka@kosmik1:/junk$ python meh.py
(1*x+2y)**4
(1*x+2y)**4
Traceback (most recent call last):
  File "meh.py", line 33, in <module>
    print(re.search(pattern,expr).groups())
AttributeError: 'NoneType' object has no attribute 'groups'

Kód: [Vybrat]
!/usr/bin/env python3.1
# -*- coding: utf-8 -*-

import re

pattern = re.compile(r'''
^               # začiatok reťazcu
\(              # číselné vyjadrenie je v zátvorke
(               # nasledujúci blok zachytávame - jednotlivé vyjadrenie čísla

(               # zachytávame číslo, ktoré násobí vyjadrenie
[-+]?           # predpokladáme, že prvý znak bude znamienko, ale nemusí byť
\d*             # ľubovolný číselný výraz, ktorý "násobí" hodnotu výrazu
)?              # nevyžadujeme ho povinne - násobenie

(               # zachytávame jednotlivé premenné
([a-z]) # nejaké alfabetické vyjadrenie výrazu (písmeno), ktorý zachytávame
(?:^|\*\*)      # ľubovolný "umocňovateľ"
(\d*)           # mocniteľ
)+              # je striktne vyžadovaný

)               # blok je u konca
{2}             # vyžadujeme ho dvakrát
\)              # koniec číselného vyjadrenia

(?:^|\*\*)      # mocniteľ...
(\d+)           # ľubovolná mocnina zátvorky
$                       # koniec reťazcu
''', re.VERBOSE)

expr = raw_input()
print(expr)
print(re.search(pattern,expr).groups())
#print(pattern.search(expr).groups())
Název: Re: Regulárny výraz (Python) - chyba pri kompilácií
Přispěvatel: YaD 09 Srpna 2011, 22:11:31
Moc díky. S tým sa už pohrám :).
Název: Re: Regulárny výraz (Python) - chyba pri kompilácií
Přispěvatel: starenka 09 Srpna 2011, 22:12:00
nejlepsi je si na to napsat test, pokud si na pochybach...
Název: Re: [VYRIEŠENÉ] Regulárny výraz (Python) - chyba pri kompilácií
Přispěvatel: YaD 09 Srpna 2011, 22:13:12
Pravda, len s týmto sa hrám značne bokom, keďže píšem kde čo iné, takže to aj tak vyzerá.

V každom prípade K+.  ;)
Název: Re: [VYRIEŠENÉ] Regulárny výraz (Python) - chyba pri kompilácií
Přispěvatel: starenka 09 Srpna 2011, 22:24:35
NP, fakt si to podchyt tim testem, ala (hodne z rychliku):

Kód: [Vybrat]
starenka@kosmik1:/junk$ cat meh.py
#!/usr/bin/env python3.2
# -*- coding: utf-8 -*-

import re
import unittest

pattern = re.compile(r'''
^               # začiatok reťazcu
\(              # číselné vyjadrenie je v zátvorke
(               # nasledujúci blok zachytávame - jednotlivé vyjadrenie čísla

(               # zachytávame číslo, ktoré násobí vyjadrenie
[-+]?           # predpokladáme, že prvý znak bude znamienko, ale nemusí byť
\d*             # ľubovolný číselný výraz, ktorý "násobí" hodnotu výrazu
)?              # nevyžadujeme ho povinne - násobenie

(               # zachytávame jednotlivé premenné
([a-z]) # nejaké alfabetické vyjadrenie výrazu (písmeno), ktorý zachytávame
(?:^|(\*\*))    # ľubovolný "umocňovateľ"
(\d*)           # mocniteľ
)+              # je striktne vyžadovaný

)               # blok je u konca
{2}             # vyžadujeme ho dvakrát
\)              # koniec číselného vyjadrenia

(?:^|(\*\*))    # mocniteľ...
(\d+)           # ľubovolná mocnina zátvorky
$                       # koniec reťazcu
''', re.VERBOSE)

class ReTest(unittest.TestCase):
    VALID_EXPRS = ['(x^2+5y)^2','(1*x+2y)**4']
    NOT_VALID_EXPRS = ['(1*x+2y)*4','(a+b)^2']

    def test_ok(self):
        for expr in self.VALID_EXPRS:
            print(expr)
            self.assertEqual(True,bool(re.search(pattern,expr)))

    def test_bad(self):
        for expr in self.NOT_VALID_EXPRS:
            print(expr)
            self.assertEqual(False,bool(re.search(pattern,expr)))

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


starenka@kosmik1:/junk$ python meh.py
(1*x+2y)*4
(a+b)^2
.(x^2+5y)^2
F
======================================================================
FAIL: test_ok (__main__.ReTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "meh.py", line 39, in test_ok
    self.assertEqual(True,bool(re.search(pattern,expr)))
AssertionError: True != False

----------------------------------------------------------------------
Ran 2 tests in 0.000s

FAILED (failures=1)

Název: Re: [VYRIEŠENÉ] Regulárny výraz (Python) - chyba pri kompilácií
Přispěvatel: YaD 09 Srpna 2011, 22:34:56
Pravda, unit testovanie chce svoj čas, ale teraz skôr skladám ten regulárny výraz napísať od jednoduchého k zložitému, keďže vyššie spomenuté som napísal celé v kuse.

Nič iné ako znovu díky ti nemôžem povedať :).
Název: Re: [VYRIEŠENÉ] Regulárny výraz (Python) - chyba pri kompilácií
Přispěvatel: starenka 09 Srpna 2011, 22:36:04
(sem to jeste potunil - cekni znova ten kod). no od toho ten test je... nahazis si co chces a co ne a pak je tunis ten regular a nemusis to rucne zkouset, cili to pomaha UZ pri tom, co to pises
Název: Re: [VYRIEŠENÉ] Regulárny výraz (Python) - chyba pri kompilácií
Přispěvatel: YaD 09 Srpna 2011, 22:41:45
Tak ja len v terminále ťuknem na šipku hore, keďže mám jeden vstup na súbore:
Kód: [Vybrat]
$ python3 expr.py < test.in
Ale zistil som teraz, že bude trochu problém s tým ako získať informácie odtiaľ, keďže {2} (kvantifikátor, ak si správne spomínam?) mi to zakryje posledný vstup a ja som tajne dúfal, že to spraví rekurzívne, že to bude n-tica v n-tice, ale akosi smola. Takže idem pátrať a bádať, aby som sa nemusel rozpisovať cez viac riadkov...
Název: Re: [VYRIEŠENÉ] Regulárny výraz (Python) - chyba pri kompilácií
Přispěvatel: starenka 09 Srpna 2011, 22:46:08
jasne, jinak bych to taky nedelal. Nicmene vyhoda toho testu je to, ze to testuje klidne zilion vstupu naraz (a taky mnohem rychlejc, nez bys to stacil odsipkovat)

ad problem: nejsem sem si jistej, ze ti rozumim, ale i tak gl.
Název: Re: [VYRIEŠENÉ] Regulárny výraz (Python) - chyba pri kompilácií
Přispěvatel: YaD 09 Srpna 2011, 22:51:20
Vyriešené nadobro.
No, chyba spočívala v tom, že mocnina bola vyžadovaná povinne, takže opravené to je nejako takto (narýchlo skopírované):
Kód: [Vybrat]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re

pattern = re.compile(r'''
^ # začiatok reťazcu
\( # číselné vyjadrenie je v zátvorke
( # nasledujúci blok zachytávame - jednotlivé vyjadrenie čísla

( # zachytávame číslo, ktoré násobí vyjadrenie
[-+]? # predpokladáme, že prvý znak bude znamienko, ale nemusí byť
\d* # ľubovolný číselný výraz, ktorý "násobí" hodnotu výrazu
) # nevyžadujeme ho povinne - vnútri bloku nemusí prísť k zhode

( # zachytávame jednotlivé premenné
([a-z]) # nejaké alfabetické vyjadrenie výrazu (písmeno), ktorý zachytávame
(?:\^|\*\*)? # ľubovolný "umocňovateľ"
(\d*) # mocniteľ
)+ # je striktne vyžadovaný

) # blok je u konca

( # nasledujúci blok zachytávame - jednotlivé vyjadrenie čísla

( # zachytávame číslo, ktoré násobí vyjadrenie
[-+]? # predpokladáme, že prvý znak bude znamienko, ale nemusí byť
\d* # ľubovolný číselný výraz, ktorý "násobí" hodnotu výrazu
) # nevyžadujeme ho povinne - vnútri bloku nemusí prísť k zhode

( # zachytávame jednotlivé premenné
([a-z]) # nejaké alfabetické vyjadrenie výrazu (písmeno), ktorý zachytávame
(?:\^|\*\*)? # ľubovolný "umocňovateľ"
(\d*) # mocniteľ
)+ # je striktne vyžadovaný

)

\) # koniec číselného vyjadrenia

(?:\^|\*\*)? # mocniteľ...
(\d+) # ľubovolná mocnina zátvorky
$ # koniec reťazcu
''', re.VERBOSE)

print(pattern.search(input()).groups())

Problém, ale stále mám v tom, že to tam držím zduplikované, aby som sa dostal k valídnemu výsledku pre analýzu, ale hlavne, že to ide. Už len tie testy :).