Nie upodabniaj się do komputera, lecz staraj się upodabniać komputer do siebie.
grepWin jest bezpłatnym programem służącym do wyszukiwania i zamiany tekstu w plikach tekstowych. Program wykonuje swoje zadania przy pomocy zwykłego wyszukiwania tekstowego lub używając wyrażeń regularnych. Przydatne kiedy chcemy wyszukać podobne, ale nie jednakowe fragmenty tekstu w wielu plikach.
W informatyce wyrażenia regularne, nazywane także w skrócie regex lub regexp (ang. regular expressions), umożliwiają w zwięzły i elastyczne sposób na dopasowywanie ciągów znaków tekstowych, takich jak litery, słowa lub wzorce znaków. Wyrażenie regularne jest napisane w języku formalnym, który może być interpretowany przez procesor wyrażeń regularnych – program, który parsuje tekst lub sprawdza tekst i identyfikuje jego fragmenty, które pasują do zadanej poprzez wyrażenie regularne specyfikacji.

Pozycja grepWin w menu kontekstowym eksploratora widnows.

Okno wyszukiwania programu grepWin
Parę odnośników do samouczków:
Wyrażenia regularne, które każdy programista znać powinien
Wyrażenia regularne
Aplikacja Subiekt GT Sfera jest to system sprzedaży, który oprócz widocznego okienkowego interfejsu użytkownika posiada jeszcze wewnętrzny (niewidoczny dla użytkownika) interfejs. Interfejs ten to mechanizm, który pozwala na wykonywanie operacji w aplikacji Subiekt GT Sfera przez inne programy. Ujmując to inaczej – do wykonywania operacji, które normalnie wykonuje operator programu przy pomocy myszki i klawiatury można użyć odpowiednio napisanej aplikacji, która wszystkie bądź większość tych operacji wykona automatycznie – dużo szybciej i z mniejszym prawdopodobieństwem popełnienia błędu.
Sposobność do skorzystania z wyżej opisanych możliwości pojawia się kiedy:
- pojawia się uzasadniona potrzeba wprowadzenia dużej ilości danych do systemu Subiekt pochodzących z innych źródeł,
- zgromadzone w systemie dane są wykorzystywane przez inny system przetwarzający te dane,
- zaistnieje potrzeba uproszczenia pracochłonnych i powtarzalnych operacji wykonywanych w systemie Subiekt,
- należy zminimalizować użytkownikom dostęp do operacji wykonywanych w systemie jedynie do tych niezbędnych, potrzebnych do wykonania ściśle określonych zadań.
- należy odczytać i wprowadzić dane zakodowane (np. dane zakodowane kodem kreskowym GS1-128)
Każda z powyższych sytuacji skłania do zastanowienia się nad rozwiązaniem problemu. Przy pomocy aplikacji współpracującej z systemem Subiekt można pomóc rozwiązać powyższe zagadnienia. Wpierw jednak należy się zastanowić czy i jakie rozwiązania przyniosą największe korzyści.
Korzyści jakie są możliwe do osiągnięcia przez skorzystanie z możliwości systemu Subiekt GT Sfera można zebrać w kilku punktach:
- oszczędność czasu potrzebnego na wykonywanie operacji w systemie (wystawiania dokumentów, aktualizacji danych o produktach, tworzenia zestawień i raportów),
- zminimalizowanie możliwości niepoprawnego wprowadzenia danych bądź zupełne wyeliminowanie pomyłek,
- oszczędność zasobów wymaganych do wyszkolenia użytkownika do obsługi systemu Subiekt GT na rzecz zapoznania się jego jedynie z aplikacją o prostym, mało złożonym interfejsie – szybkie wdrożenie użytkownika do pracy z systemem
- dostosowanie do procedur obowiązujących w organizacji do wdrożonego weń systemu.
Łączenie się z bazą danych to jedna z podstawoych operacji, które się wykonuje tworząc oprogramowanie. Przedstawiam przykład jak w prosty sposób połączyć się z bazą danych.
Bez pomocy kreatora można w prosty sposób utworzyć źródło danych oraz podłączyć je do odpowiedniej kontrolki. Podłużę się w tym celu przykładową bazą danych instalowaną razem z serwerem bazy danych SQL Server Compact 3.5.
Komentarze w kodzie opisują resztę. Dla zainteresowanych plik projektu w załączeniu.
'import modułu do obsługi serwera SQL Compact
Imports System.Data.SqlServerCe
Public Class formProductBrowser
'Połączenie z bazą danych.
Private conn As SqlCeConnection
'Zmienne przechowująceo "connection string".
Private database_path, con_string As String
'Data set - przechowuje dane w pamięcid.
Private ds As New DataSet
' Przygotowanie komend do wykonania na bazie '
Private cmd_select, cmd_update As SqlCeCommand
'Tabela z danymi pobranymi z bazy danych.
Private my_table As New System.Data.DataTable()
' Adapter - reprezentuje zestaw komend na danych i połączenie z bazą
' używane do wypełniania DataSet
Private my_adapter As New SqlCeDataAdapter()
'Identyfikator i cena produktu
Private product_id As Integer
Private unit_price As Decimal
'Nazwa tabeli i pól
Private nazwa_tabeli As String
'Nazwa pola ID
Private nazwa_id As String
'Nazwa pola do modyfikacji
Private nazwa_do_mod As String
'Nazwa pola do modyfikacji
Private nazwa_sort As String
Private Sub formEmployeesBrowser_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
nazwa_tabeli = "Products"
nazwa_do_mod = "Unit Price"
nazwa_id = "Product ID"
nazwa_sort = "Product Name"
' Otwarcie połączenia.
database_path = "C:\Program Files\Microsoft SQL Server Compact Edition\v3.5\Samples\Northwind.sdf;"
con_string = "Data Source = " & database_path & ";Persist Security Info=False;"
conn = New SqlCeConnection(con_string)
conn.Open()
' Utworzenie komend do operacyj na zbiorze danych.
cmd_select = conn.CreateCommand()
cmd_select.CommandText = "SELECT * FROM " & nazwa_tabeli '& _
'" ORDER BY '" & nazwa_sort & "';"
my_adapter.SelectCommand = cmd_select
my_adapter.UpdateCommand = cmd_update
'Wypełnianie DataSet danymi z bazy
my_adapter.Fill(ds, nazwa_tabeli)
my_table = ds.Tables(nazwa_tabeli)
'Wypełnienie pola kombo z produktami
cmbProduct.DataSource = my_table
cmbProduct.DisplayMember = "Product Name"
cmbProduct.ValueMember = nazwa_id
End Sub
Private Sub cmbProduct_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbProduct.SelectedIndexChanged
lblProdId.Text = cmbProduct.SelectedItem(0)
lblQtyPerUnit.Text = cmbProduct.SelectedItem(5)
txtUnitPrice.Text = cmbProduct.SelectedItem(6)
lblProdName.Text = cmbProduct.SelectedItem(3)
End Sub
Private Sub formEmployeesBrowser_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
If conn.State = ConnectionState.Open Then
conn.Close()
End If
End Sub
Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
Me.Close()
End Sub
End Class
Dla przykładu nie należy polegać na implementacji łączenia ciągów “w miejscu” (in-place) w formie a+=b lub a=a+b. Takie deklaracje wykonują się dużo wolniej w Jython. W częściach biblioteki gdzie wydajność jest szczególnie ważna w zamian powinna być użyta konstrukcja ”.join(). Taka konstrukcja daje pewność, że połączenie zdarzy się liniowo w czasie pośród różnych implementacji.
Wystrzegać należy się pisania if x kiedy ma się na myśli if x is not None — np. kiedy testuje się czy danej zmiennej czy argumentowi, który domyślnie przyjmuje wartość None została przypisana inna wartość. Inne wartości mogą mieć taki typ (tak jak kontener), że jest on fałszywy w kontekście booleanowskim (?).
Wyjątki typu string w nowym kodzie są zabronione, ponieważ ta właściwość języka zostanie usunięta w Pythonie 2.6.
Moduły i pakiety (packages) powinny definiować własne specyficzne dla siebie klasy wyjątków (exception class), które powinny dziedziczyć z wbudowanej (built-in) klasy wyjątków. Zawsze należy zawierać docstringa klasy.
Mają tutaj również zastosowanie konwencje nazewnictwa klas, chociaż powinno dodawać się sufiks Error do nazwy klasy wyjątku, jeśli wyjątek jest błędem. Wyjątki “nie-błędy” nie potrzebuję specjalnego sufiksu.
class MessageError(Exception): """Base class for errors in the email package."""
Forma z nawiasami jest preferowana, ponieważ kiedy argumenty wyjątku są długie lub zawierają formatowanie ciągów nie zachodzi potrzeba używania znaku kontynuacji linii dzięki otoczeniu nawiasami. Starsza forma będzie niedostępna w Pythonie 3000.
Na przykład:
try: import platform_specific_module except ImportError: platform_specific_module = None
Samotna klauzula except przechwyci także wyjątki SystemExit i KeyboardInterrupt, co uczyni trudniejszym przerwanie działania programu przy pomocy
Dobrą zasadą jest ograniczyć użycie czystego except do dwóch przypadków:
Tak:
try: value = collection[key] except KeyError: return key_not_found(key) else: return handle_value(value)
Nie:
try: # Too broad! return handle_value(collection[key]) except KeyError: # Will also catch KeyError raised by handle_value() return key_not_found(key)
Metody stringów są zawsze dużo szybsze i współdzielą to samo API ze stringami unikod.
startswith() i endswith() są czystsze i powodują mniej błędów. Na przykład:
Tak:
if foo.startswith('bar'):
Nie:
if foo[:3] == 'bar':
Tak:
if isinstance(obj, int):
Nie:
if type(obj) is type(1):
Podczas sprawdzania czy obiekt jest stringiem, należy mieć na uwadze, że to również może być string unikodowy! W Pythonie 2.3 string i unikod mają wspólną klasę bazową, basestring, tak więc można zrobić:
if isinstance(obj, basestring):
Tak:
if not seq: if seq:
Nie:
if len(seq) if not len(seq)
Tak:
if greeting:Nie:
if greeting == True:
Jeszcze gorzej:
if greeting is True:
Napisane na podstawie PEP 8 . Nie jestem profesjonalistą, ale staram się. Tekst jest pomocą przede wszystkim dla mnie. Jeśli komuś jeszcze będzie on pomocny ucieszę się. Jeszcze bardziej będę zadowolony jeśli ktoś doświadczony tu zajrzy i zechce skomentować to, i tamto.
Istnieją pewne rekomendowane konwencje nazewnictwa w Pythonie. Konwencje te powinny być stosowane do nowo pisanych modułów. Nowo pisane pakiety i moduły powinny być utrzymane w tych konwencjach. Kiedy starsza biblioteka reprezentuje inny styl to przy jej rozszerzaniu powinien być zachowany pierwotny styl w celu wewnętrznej spójności.
Nie używać jako nazw zmiennych liter l (L jak Leszek), O (O jak Olga) oraz I (i jak Irena). W przypadku pewnych krojów czcionek litery te są nieodróżnialne od liczby jeden oraz zero.
Moduły powinny mieć krótką nazwę wyłącznie z małych liter. Podkreślenia mogą być używane w nazwach modułów jeśli poprawi to czytelność. Podobnie jest w przypadku pakietów (ang. package) jednak nie zaleca się stosować podkreśleń.
Ponieważ nazwy modułów są mapowane do nazw plików powinny one być odpowiednio krótkie. Zbyt długie nazwy mogą być problemem na starszych wersjach Mac, Windows oraz w DOS.
Kiedy rozszerzeniu napisanym w C/C++ towarzyszy moduł Pythona dodający interfejs wyższego poziomu (bardzo zorientowany obiektowo), nazwa rozszerzenia w C/C++ powinna rozpoczynać pojedynczym podkreśleniem (np. _socket)
Prawie że bez wyjątków, nazwy klas powinny mieć nazwę w konwencji CapsWords. Klasy do użytku wewnętrznego powinno poprzedzać pojedyncze podkreślenie (_CapsWord).
Nazwy funkcyj powinny być pisane małymi literami ze słowami rozdzielanymi przez podkreślenia, jeśli to konieczne aby zwiększyć czytelność (nazwa, nazwa_funkcji)
Zawsze należy używać self jako pierwszego argumentu do metody instancji. Zawsze należy używać cls jako pierwszego argumentu do metody klasy.
Jeśli nazwa argumentu funkcji koliduje z nazwą słowa kluczowego Pythona, zazwyczaj lepiej jest dołączyć pojedyncze podkreślenie na końcu nazwy niż tworzyć nieczytelne skróty lub celowe literówki. W związku z tym print_ jest lepsze niż prnt. Dobrze jeśli uda się uniknąć konfliktu przez użycie synonimu.
Nazwy zmiennych globalnych podlegają tym samym konwencjom co nazwy funkcyj. (Zaleca się aby używać zmiennych globalnych tylko wewnątrz jednego modułu)
Moduły, które są zaprojektowane aby używać ich przez from module import * powinny zawierać mechanizm __all__ aby zapobiec eksportowaniu zmiennych globalnych lub stosować starszą konwencję dołączania przedrostka – pojedynczego podkreślenia (co można chcieć zrobić by wskazać te zmienne globalne jako “niepubliczne”).
Stosować zasady dotyczące nazw funkcyj.
Poprzedzające pojedyncze podkreślenie dla niepublicznych metod i zmiennych instancji.
Unikać konfliktu nazw z podklasą przez użycie podwójnego poprzedzającego podkreślenia aby wywołać mechanizm dekorowania nazw Pythona (Python’s mangling rules).
Stałe są deklarowane na poziomie modułu i pisane wielkimi literami z pokreśleniami jako separatorami słów. Np. MAX_OVERFLOW i TOTAL.
Zawsze należy zdecydować czy metody i zmienne instancji (wspólne określenie to atrybuty) mają być publiczne czy niepubliczne. W razie wątpliwości należy uczynić atrybut niepublicznym, później łatwiej zrobić z niego atrybut publiczny niż na odwrót.
Publiczne atrybuty to te, co do których należy się spodziewać, że będą użyte przez niezwiązane klienty, ze “zobowiązaniem”, że zmiany w module/pakiecie nie będą powodowały niekompatybilności wstecz. Niepubliczne atrybuty to te, które nie są tworzone w zamierzeniu do użycia przez programy trzecie. Nie ma potrzeby zapewniać, że niepubliczne atrybuty nie zmienią się lub nawet nie będą usunięte.
Używa się terminu “niepubliczny” gdyż tak na prawdę żaden atrybut w Pythonie nie jest prywatny.
Kolejna kategoria atrybutów to te, które są częścią “podklasowego API” (”subclass API”) – nazywane w innych językach programowania – protected. Niektóre klasy są przeznaczone do dziedziczenia aby rozszerzać lub modyfikować różne aspekty zachowania klasy. Podczas projektowania takiej klasy należy podjąć wyraźne decyzje dotyczące tego jakie atrybuty mają być publiczne, a które są częścią “podklasowego API”, i które będą na prawdę używane tylko przez klasę bazową.
Biorąc pod uwagę powyższe, oto Pythonowe wskazówki.
Zobacz powyższe rekomendacje dla nazewnictwa metod klas.
PEP 8 to jest podręcznik z wytycznymi na temat stylu kodu w Pythonie, a powyższy tekst to moja ściąga z PEP 8, napisana na poziomie mojej wiedzy z języka Python. Ma służyć dla mnie jako pomoc w opanowaniu języka.
Do późniejszego uzupełnienia.