Napisałem skrypt w Bashu, który zmusi wszystkich zalogowanych użytkowników do wylogowania się. Musiałem napisać, ponieważ mój skrypt do robienia automatycznych kopi zapasowych, o którym pisałem w Anacron + Tar = automat do robienia kopii zapasowych, wykłada się, gdy użytkownik robi coś w archiwizowanych katalogach. Użytkownik pewnie by się wylogował... gdyby pamiętał, że akurat tego dnia jest robiona kopia zapasowa.
Co może być takiego trudnego we włączeniu kompresji GZIP na stronie? Prawdopodobnie nic, jeśli ma się dostęp do pliku php.ini lub dyrektywy "php_value" w pliku .htaccess działają. Jednak na serwerze wirtualnym (w większości przypadków) takiej wygody nie mamy. A i żeby nie było nie chodzi mi tu o kompresje plików z końcówką .php, bo to się włącza kilkoma linijkami. Rzecz rozbija się o kompresję plików .css, .js, czyli plików nieprzetwarzanych przez interpreter php.
Ostatnio przez problem referencji w foreach i burzę mój blog był nieużywalny przez prawie pół dnia. Kod mojego CMS jest bardzo rozbudowany, więc uchwycenie tego błędu było bardzo trudne, lecz najgorsze chyba było to, że nawet bym tego nie podejrzewał o powodowanie się wysypywania kodu. To jest bardziej nieuchwytne niż niezaincjowawany wskaźnik w C++.
Człowiek robi męczące rzeczy z dwóch powodów. Pierwszy powód to czysta ciekawość, a drugi powód to konieczność. Otóż mój kolega posiada Windowsa i chce testować mój program do nauki słówek Konkord, też lubi tak jak uczyć się języków obcych. Niestety nigdy nic nie kompilowałem na Windowsie, musiałem opierać się na skromnych informacjach z Internetu, a najlepsze jest to, że nie było nic po polsku.
MinGW kontra Cygwin
Przechodząc do sedna sprawy, na moim Debianie kompiluję swój program gcc, gdy kiedyś na Windowsie pracowałem, programy kompilowałem MinGW dołączonym do środowiska developerskiego DevC++ (lecz wtedy nie wiedziałem, że używam jakiegoś MinGW). Lecz teraz wiedziałem, że chcą budować aplikację linuksową na Windowsa, mam dwie możliwości, albo zainstalować Cygwina - implementację standardu POSIX dla systemów z rodziny Windows, albo użyć kompilatora MinGW - gcc przeportowanego na systemy z rodziny Windows.
Cygwin zapewniał by mi to, że nie musiałbym zmieniać kodu programu, ani przekompilowywać zewnętrznych bibliotek, których w nim używam, lecz zmusiłbym również tym użytkowników do instalacji Cygwina, a oni raczej nie chcieli by instalować takiego kombajna dla jednego kilkudziesięcokilobajtowego (bez wkompilowanych bibliotek) programu.
MinGW tworzy mi program z rozszerzeniem .exe, który będzie działał na każdym Windowsie i będzie samowystarczalny. Jednak w tym wypadku będę musiał przekompilować biblioteki i je dołączyć do program i czasem zmienić kod programu.
Zdecydowałem się na drugie rozwiązanie, dużo czasu poświęciłem na wstępne przygotowywania, czyli na to, żeby zainstalować i skompilować to, co będzie mi potrzebne do skompilowania programu. Nie żebym aż tak długo się zastanawiał, lecz te pakiety trochę ważą.
Czy zastanawiałeś się kiedyś jak za pomocą prostych narzędzi zrobić skrypt, który będzie automatycznie robił codziennie kopię zapasową wybranych przez Ciebie folderów na dysku? Taki automat można zrobić z prostych narzędzi dostępnych w każdej dystrybucji linuksowej: Tara i Anacrona. Trochę poszukałem i znalazłem posta na debian.linux.pl, trochę dodałem od siebie i wyszedł mi dość prosty i użyteczny skrypt.
Podczas wprowadzenia zmian i testowania programu do nauki słówek wykryłem błąd, który nie był zwykłą literówką, lecz błędem w strukturze programu, pojawiającym się raz na ileś. Taki błąd jest najgorszy, bo trudno odgadnąć, dlaczego to program się wyspuje, jest trudny do uchwycenia. Z tym błędem wiązało się też, że rozwiązując go, musiałem stanąć przed dylematem, które rozwiązanie wybrać.
Zaprezentuję przykład, gdzie będzie ten sam błąd
#include
#include
using namespace std;
int main() {
vector elements;
int **wsk_to_elements = new int*[10000];
for(int i = 0; i < 10000; i++) {
elements.push_back(i);
wsk_to_elements[i] = &elements[i];
}
for(int i = 0; i < 10000; i++) {
elements.push_back(i);
}
vector elements2;
for(int i = 0; i < 100; i++) {
elements2.push_back(i+10000);
}
for(int i = 0; i < 10000; i++) {
cout << *wsk_to_elements[i] << endl;
}
return 0;
}
Niby wszystko w porządku, ale… po skompilowaniu i uruchomienu raczej zobaczymy, że 100 pierwszych wskaźników z tablicy wsk_to_elements wskazuje nam na jakieś elementy, których wartość jest większa od 10000, czyli chyba elementy vectora elements2. Dlaczego? Vector to taki obiekt, który przechowuje nam elementy, pozwala nam dodawać i usuwać elementy w każdej chwili, ale też stara się zachować ciągłość w pamięci, dlatego gdy przy dodaniu 1000 elementu vector widzi, że na nie ma już miejsca na prawo, to przenosi wszystkie elementy do takiego miejsca w pamięci, gdzie będzie mógł dodać ten 1000 element. Krótko mówiąc, nie gwarantuje nam, że elementy będą cały czas w tym samym miejscu w pamięci. Można się przed tym zabezpieczyć rezerwując miejsce na x elementów, dając mu x w konstuktorze, ale przecież nie zawsze wiemy, jaki rozmiar nam będzie potrzebny. Dlatego użycie wskaźników na elementy vectora jest samobójstwem.
I właśnie taki błąd miałem w programie i miałem do wyboru kilka możliwości rozwiązania problemu:
I. Posłużyć się iteratorami, ale w praktyce wyglądałoby to tak:
class SingleWord {
//…
vector::iterator something;
//…
}
class Kurs {
//…
vector singleWords;
//…
Trochę głupio uzależniać klasę SingleWord, która ma być niezależna od klas ją wykorzystujących. W porównaniu do drugiego rozwiązania zachowałbym taki sam czas dostępu do elementów.
I rozwiązanie nie jest rozwiązaniem, bo ma te same wady, co rozwiązanie oparte na wskaźnikach. Rozwiązaniem podobnym do tego opartego na iteratorach byłoby:
class SingleWord {
//…
unsigned int something; //numer słowa w vectorze
//…
}
class Kurs {
//…
vector singleWords;
//…
To rozwiązanie ma jedną zasadniczę wadę: klasa SingleWord jest zależna od klasy ją wykorzystującej Kurs.
II. W samym vectorze posłużyć się wskaźnikami, wyglądałoby to tak:
class SingleWord {
//…
SingleWord *something;
//…
}
class Kurs {
//…
vector singleWords;
}
W tym rozwiązaniu klasa SingleWord zachowuje swoją niezależność, ale jest trochę wolniejszy dostęp do elementów z klasy Kurs, bo odbywa się przez wskaźniki. To, że w vectorze są wskaźniki, ma jeszcze inną zaletę, gdy vector będzie zmieniał swoje miejsce w pamięci, nie będzie kopiował ponad 100 bitowego elementu klasy SingleWord, lecz 64 bitowe wskaźniki. Oczywiście nie należy zapomnieć, że tym przypadku musimy samodzielnie zwalniać pamięć, vector.erase() usunie tylko wskaźniki, elementy, na które wskazywały zostaną.
Wybrałem II rozwiązanie, lecz zaskutkowało to tym, że musiałem zmieniać działanie wielu funkcji. Przy okazji tych zmian, stwierdziłem, że gdy chcę odmówić prawa do zmieniania elementu, lepiej zwrócić "wskaźnik na stały element" niż "element", program będzie szybciej działał, ponieważ wskaźnik jest tylko 64 bitowy. Zmieniłem… lecz mocno się zdziwiłem, bo funkcja wygląda tak:
Wyszła wersja 0.1 mojego programu do nauki słówek. Narazie posiada tylko tryb tekstowy. Udało mi się spełnić kilka punktów z listy TODO:
Uporządkowałem i zwiększyłem przejrzystość kodu
W większości nazwy zmiennych, funkcji, klas pozmieniałem na angielskie
Średniozaawansowana obsługa błędów
Dodane wyszukiwanie słówek
Dodane wczytywanie słówek z pliku
Dodałem plik Makefile
Oprócz tego zlikwidowałem wiele błędów. Program się rozwija i pewnie zaniedługo ujrzycie jego kolejną o wiele lepszą wersję.
Pobierz Konkord 0.1(kod źródłowy)
Zamierzam napisać o programie do nauki słówek np. z języka angielskiego, który stowrzyłem. Nazwałem go "konkord", chyba dlatego, że wpadłem na pomysł stworzenia tego programu, gdy grałem w gierkę, gdzie jeździ gokardami. Na chwilę obecną ten program jest jeszcze w wersji alfa, więc proszę się liczyć z tym, że korzystanie z niego może przyprawić o ból głowy.
Idea
Uczęszczam do 3 klasy gimnazjum, dla niezoreintowanych, w tej klasie pisze się egzamin gimnazjalny, to oznacza, że jest masa do nauki, do przedmiotów, z których wiedza wymagana przy zdawaniu poszczególnych części tego egzaminu. I tak się składa, że mój rocznik, jako pierwszy pisze test gimnzjalny z języka obcego(ja z angielskiego). Nauczyciel z angielskiego się uwziął i jest masa słówek do wykucia, na próbnym egzaminie nie umknęło moje uwadze, że wymagane są duże zasoby słownictwa. Stwierdziłem też, że metoda, zakrywania dłonią angielskich odpowiedników lub polskich i odpytywanie się choć była wcześniej efektywna, teraz jest nieefektywna, gdyż masę czasu tracę na przepytywanie się ze słówek, które już umię. Więc postanowiłem stworzyć program z mechanizmem, który na podstawie wyników poprzednich przepytywań określałby w jakim stopniu dane słowo umiem, i po jakim czasie je zapomnę, i który przepytywałby mnie z tych słów najmniej opanowanych. A że ja często pomysły wcielam w życie, to więc i ten wcieliłem; po napisaniu 400 linijek silnika nie mogłem się wycofać.
Licencja
Program jest dostępny na licencjiGNU GPL(wersja 3). Zdecydowałem się wybrać tą licencję, ponieważ całkowicie obcja jest mi idea licencji zamkniętych oraz jestem zbyt przywiązany do tego programy, aby go udostępnić na licencji BSD.
Funkcje
Program jest narazie w czesnym stadium rozwoju, określiłbym ten stan jako pre-alpha. Na dziś stworzony jest silnik bez zaawansowanej obsługi błędów, nakładka tekstowa na silnik.
Silnik potrafi:
tworzyć, zapisywać kurs do pliku oraz wczytywać z pliku,
przepytywać ze słówek oraz uczyć nowych słówek,
określać w jakim stopniu umi się dane słowa.
Nakładka tekstowa:
potrafi obsługiwać kilka kursów naraz,
ma rozbudowane menu,
nie ma skrotów klawiszowych.
Konkursy się skończyły(zaniedługo pochwalę się wynikami), będę miał więcej czasu, więc udoskonalę program.
Plany
Ogólnie:
uporządkować kod,
nazwy zmiennych pozmieniać na angielskie,
zwiększyć przejrzystość kodu,
dodać więcej komentarzy
Silnik:
dodać ustawienia programu,
dodać osblugę wielu języków,
dodać zaawansowaną obsługę błędów,
dodać wyszukiwanie słówek po nazwie,
dodać dodawanie słówek z pliku.
Nakładka:
dodać obsługę skrótów klawiszowych,
przenieść nakładkę na bibliotekę ncurses,
dodać ustawienia nakładki.
Pobierz program
Kompiluje się poleceniem: "g++ main.cpp kurs.cpp -o konkord".
Tagi: białe znaki, C++, cin, funkcje, programowanie, scanf, standardowe wejście, STL, wczytywanie danych, Kategoria: Informatyka Niestety ja się za późno o tym dowiedziałem i m.in. przez to uzyskałem słaby wynik w II etapie OIG. Nie wiedziałem jak pobrać np. 100 zmiennych podanych w jednej lini, przez funkcje scanf jest to nieefektywne, pobranie stringa a później rozbijanie go na liczby też nie jest efektywne.
Więc zacząłem szperać po necie i znalazłem takie info, że jak będę chciał pobrać przez cin pobrać "ala ma kota" to pobierane jest tylko "ala" a reszta pozostaje do późniejszego odczytania. To znaczy, że jakbym miał program:
To wpisując raz "ala ma kota" to "ala" byłaby w _1, "ma" w _2, "kota" w _3(a ja myślałem, że wszystko po pierwszym białym znaku jest kasowane). Teraz pobranie kilku wyrazów, liczb podanych w jednej lini odzdzielonych od siebie białym znakiem(np. spacja, "/t") jest dla mnie proste.
Tagi: programowanie, spolszczenie, Sport, webmastering, wiosna, Wordpress, ZaDiS, zmiany, Kategoria: Reszta Przepraszam was drodzy czytelnicy, że nie pisałem tak długo, ale nie miałem czasu.
Nadeszła wiosna, więc trzeba zacząć biegać, ćwiczyć, grać w i piłkę nożną. Biegać jeszcze nie zacząłem, ale zacząłem już chodzić na treningi do klubu piłkarskiego w mojej miejscowości.
Musiałem też zainstalować Wordpress 2.5, ale nie wiem czego spolszczenie mi nie działa, chociaż zrobiłem to co trzeba, czyli wrzuciłem pliku pl.mo i pl.po do "/wp-content/languages/" , później do "/wp-includes/languages/" i dalej nie działa. Będę musiał pokombinować :/ .
W związku z tym, że dostałem się do drugiego etapu OIG, musiałem trochę poprogramować, a czasu dużo nie mam drugi etap już w sobotę. Jeśli chodzi o programowanie, to mam zamiar stworzyć klasę AWK(taki język programowania, wiecej na wikipedi oraz na blogu zyxist.com) w C++ i D. Jeśli chodzi o programowanie, zrozumiałem, też, że nowe języki, choć są bardzo dobre i nowoczesne, nie zdobędą popularności, bo większość przyzwyczaja się do tych starszych, jedyna nadzieja w nastolatkach, którzy teraz zaczynają programować lub programują.
Wiem, wiem, że kolejne głupie wytłumaczenie, ale musiałem też zająć stronką klanu SoW(do którego ja należę) z CounterStrike, więc musiałem się pomęczyć z logo we Flashu, oraz z innymi zachciankami członków SoW.
Musiałem jeszcze bawić się z hostingiem, ale o tym w innym wpisie.
PS. Jeszcze jednej zachcianki nie spełniłem.
Teraz już nie zrobię takiej dużej przerwy, bo nie mam powodów i głupich wymówek oraz mam bardzo dużo wpisów w planie :D . Więc spodziewajcie się tu dużo ciekawych wpisów.
Do napisania tego wpisu zainspirował mnie artykuł o tym, że Microsoft się otwiera. Dotąd prowadził on wojnę z Linuksem, otwartym oprogramowanie, straszył pozwaniem do sądu za naruszone(?) patenty. A teraz się obudził i zdał sobie sprawę w przeciwieństwie do Don Kichote, że to była "walka z wiatrakami".
Wydawać by się mogło, że w środowisku wolnego, otwartego oprogramowania FLOSS nie ma ludzi skłóconych, a wszyscy ludzie stoją po jednej stronie, nie bardziej mylnego. Środowisko to jest podzielone na dwa większe fronty, jeden to posługujący się licencją GNU GPL, głosem ich FSF(Free Software Fundation) oraz nieformalny przywódca, Richard Stellman, ich symbolem jest głowa antylopy. Natomiast drugi front, to ludzie bardziej liberalny, ich nieformalnym przywódcą jest Linus Torvalds, a organizacją pomocniczą jest OSI, w przeciwieństwie do pierwszego odłamu nie udało się uzyskać znaku towarowego dla Open Source, który zabraniał by innym używać tego terminu. Plotki mówią, że ci dwaj niby przywódcy się nie za bardzo lubią, ale co się dziwić mają ku temu powody. Rozgadałem się trochę na temat podziału, a zapomniałem, że ruch wolnego oprogramowanie zapoczątkował Richard Stellman w 1983 roku, ogłaszając publicznie projekt systemu GNU. Więcej o historii nie będę się rozpisywał, ponieważ kto będzie chciał sobie ją poczytać to wejdzie na Wikipedie i sprawa z głowy.
Wspomniałem w poprzednim akapicie, że coś dzieli to środowisko, wszystkiego winna jest licencja. Środowisko związane z Linuksem nie chce słyszeć o licencji, która zmusza twórców oprogramowanie, którzy mają w swoim projekcie chociaż jeden plik z licencją GNU GPL, do tego, aby ich oprogramowanie było też na licencji GNU GPL. Mówią, że to jest kolejna zaraźliwa licencja i niepotrzebnie ogranicza twórców oprogramowania, licencja powinna jak najwięcej dawać możliwości twórcom oprogramowania, aby mogła się nazywać wolną. Chcąc być alternatywą oraz odróżnić się od Wolnego Oprogramowania, nazwali swój ruch Otwartym Oprogramowaniem(org. Otwarte Źródła). Ale te dwa ruchy mają coś wspólnego, zgadzają się co do tego, że każdy może wykorzystywać, modyfikować otwarte/wolne oprogramowanie, różnice dotyczą jedynie tego, jaką może mieć licencje po zmienieniu przez użytkownika. Konflikt jest tylko widoczny na górze, wśród przywódców.
Siłą całego ruchu jest jego wielkość i to, że każdy może aktywnie uczestniczyć w tworzeniu oprogramowania, dzięki temu powstało dużo oprogramowania: Mozilla, Netscape(już praktycznie nie istnieje), G++, Linuks, GNOME, Firefox, Firebid, eMule, OpenOffice oraz typy plików: odf, gzip. Większość ludzi z tego środowiska nie chce żeby OOXHML zostało uznane przez ISO za drugi standard zapisu plików, chociaż niektórzy sympatyzują z Microsoftem np. Novell, ale wszyscy sprzeciwiają się patentom na oprogramowanie oraz uważają, że najlepsze programy mogą powstać jedynie przy dużej konkurencji oraz gdy każdy będzie miał w wgląd w ich kod, ponieważ łatwiej wtedy załatać błędy, ulepszyć. Kolejną rzeczą, która łączy dwa odłamy tego ruchu jest znak copyleft(odwrócony copyright), w wolnym tłumaczeniu znaczy tyle wszystkie prawa odwrócone, chociaż ma zastosowanie generalnie w licencjach projektu GNU. Jako kompromis pomiędzy liberalnymi licencjami np. BSD, a restrykcyjnymi typu GNU GPL, powstała licencja GNU LGPL, która najbardziej mi się podoba. Ja uważam, że jeśli wykorzystuje się owoc czyjeś pracy, to pasuje, że modyfikacja zawierające tą część też powinna być wolna, ale to należy do kwestii moralności ludzi, a nie do regulowania przez licencję.
Każdy napewno słyszał kiedyś o jakimś języku z rodziny C. Dzięki tym językom zmienił się świat. Na przykład to system Windows wyszedł dzięki językowi C, a aplikacje na komórke dzięki Javie. A ludzie swoje programowanie zaczynają najczęściej od nauki C++.