Qt i android – zaczynamy!

Przygotowanie środowiska

Do korzystania z dobrodziejstw Qt dla Androida musimy pobrać parę rzeczy:

  1. [JDK]
  2. [Android SDK]
  3. [Android NDK]
  4. [Apache Ant] lub [Gradle]

Ważne żeby pobierać najnowszą wersje tych aplikacji.

Wszystkie rzeczy warto zainstalować (wypakować) w jednym miejscu, np ja mam przeznaczony do tego folder Android, który zawiera następujące foldery:

  • android-sdk/
  • android-ndk/
  • apache-ant/
  • JDKw domyślnej lokalizacji instalacji

 

          Konfiguracja Qt

  • Tutaj sprawa jest   prosta:
    1. Uruchamiamy Qt
    2. Wchodzimy w Tools -> Options… -> Android
    3. Uzupełniamy ścieżki odpowiednio dla JDK, Android NDK/SDK oraz Ant/Gradle
    4. Zatwierdzamy zmiany

     

    Urządzenie do debuggingu

    Generalnie do testowania aplikacji możemy korzystać z 2 opcji:

    • możemy korzystać z fizycznego urządzenia,
    • możemy korzystać z maszyny wirtualnej (wirtualizować urządzenie).

Część druga już niebawem 🙂

Sztuczna inteligencja i jej zdolności!

Sztuczna inteligencja

(SI, ang. artificial intelligence, AI) – dziedzina wiedzy obejmująca logikę rozmytą, obliczenia ewolucyjne, sieci neuronowe, sztuczne życie i robotykę. Sztuczna inteligencja to również dział informatyki zajmujący się inteligencją – tworzeniem modeli zachowań inteligentnych oraz programów komputerowych symulujących te zachowania. Można ją też zdefiniować jako dział informatyki zajmujący się rozwiązywaniem problemów, które nie są efektywnie algorytmizowane. Termin wymyślił John McCarthy w 1956.

 

AutoDraw to świetny przykład.

Auto Draw wykorzystuje uczenie maszynowe. Interpretuje nasz rysunek i podpowiada gotowe formy. Możemy je zobaczyć nad tworzonym obrazkiem. Aplikacja działa z poziomu przeglądarki zarówno na pececie, jak i smartfonie czy tablecie.

Poniżej mamy przykład wykorzystania :

Arduino co po co i jak!

Arduino  warto? , a może nie?

Co to jest te całe arduino?

Arduino – platforma programistyczna dla systemów wbudowanych oparta na prostym projekcie Open Hardware przeznaczonym dla mikrokontrolerów montowanych w pojedynczym obwodzie drukowanym, z wbudowaną obsługą układów wejścia/wyjścia oraz standaryzowanym językiem programowania

 

Do nie dawna sądziłem , że arduino może  i jest warto ale dlaczego tak drogo?
Wydanie ponad 300zl za  jakiś zestaw startowy to dać się wyruchać w biały dzień ( pewna część czytelników odbierze odwrotnie tą metaforę, niż zakłada autor ) , przecież jakiś uC to kilka złotych , a rezystory , kondensatory to grosze, do tego kilka kabelków  i jakiś led to większość znajdzie w domu 🙂   – z tego powodu arduino omijałem szerokim łukiem.

Ale jak się ogląda tego Youtuba , i widzi zajebiste projekty typu self balancing robot czy ramie sterowane ręką to aż kusi by spróbować. I w sumie jak się trochę podrąży temat to nie potrzeba wcale tych „czystu” złotych. Na allegro można znaleźć proste płytki arduino już za kilkanaście zlotych , do tego płytka stykowa prototypowa jakieś drobne elementy i Voilà.

Programowanie  na początku jest banalne , jest dużo filmów , książek , artykułów , które podają nam to wszystko na talerzu.  I to jest powód aby wydać te 20 zł u kupić arduino uno – materiałów do nauki jest bardzo dużo. 

Bawiąc się w nawet małe projekty , nauczysz się programowania oraz podstaw projektowania układów elektronicznych, a przy tym jaka zabawa!

 

Poniżej przedstawiam kilka popularnych wersji arduino :

 

Arduino UNO

Arduino UNO

Arudino UNO jest następcą Duemilanove. Z pośród 14 cyfrowych pinów 6 z nich może pracować w trybie PWM. Posiada on 2KB pamięci SRAM oraz 1KB pamięci EEPROM. Jak w większości wersji Arduino częstotliwość taktowania procesora wynosi 16MHz.

 

Arduino Leonardo

Arduino Leonardo

Arduino Leonardo jest dostępny w dwóch wersjach: o niskim profilu czyli bez przylutowanych złącz (wysokość płytki 5mm) oraz w wersji ze złączami (czyli tradycyjnej). Od Arduino UNO różni się między innymi mikrokontrolerem oraz większą ilością pinów. Leonardo posiada natywną obsługę USB dzięki czemu udawanie innych urządzeń USB jest łatwe.

 

Arduino Micro

Arduino Micro

Arduino Micro jak sama nazwa wskazuje jest to płytka o nie wielkich rozmarach (podobnie jak wersja Nano, Fio, Mini, Pro Mini). Płytki tego typu są dobrym rozwiązaniem gdy chcemy je gdzieś „upchać” i nie mamy zbyt wiele miejsca. Cena podobnie jak płytka też jest niewielka 🙂 Arduino Micro posiada 20 cyfrowych pinów i 12 analogowych

Qt – zapisywanie do pliku tekstowego

Jak otworzyć i zapisać pliku , łatwo wyczytać.

ale jak dopisać?

Z tym jest trochę trudniej , ale też się da. Metodą, którą wykorzystałem w projekcie i którą chcę przedstawić, jest prymitywna, nie ma tu nic genialnego , szybkiego i magicznego. Ale jest prosta w zrozumieniu i działa.

Funkcje dopisania do pliku podzielimy na 3 etapy:

  1. odczytanie z pliku
  2. dodanie nowej tresci
  3. zapisywanie

Pierwszy etap to istna kopia poprzedniego posta , czyli taki kawałek kodu :

 

QFile plik("plik.txt");

plik.open(QIODevice::ReadOnly);

QString contents = plik.readAll().constData();

plik.close();

 

Oczywiście można dodać warunki otwarcia . sprawdzania błędu itp , itd. To jest najprostsza konstrukcja.

Etap drugi to dodanie stringów ( brzmi ciekawie)

 

      QString title ;
        title = ui->plainTextEdit_2->toPlainText();
      QString tresc ;
         tresc = ui->plainTextEdit->toPlainText();

 

Co to robi ?  To pobiera tekst z naszych pól tekstowych i zapisuje do pliku typu Qstring.

Sumujemy nasze stringi :

contents= contents+title+tresc;

Tutaj również należałoby sprawdzać i dodawać nowe akapity oraz jakoś go uporządkować.

Ostatni etap czyli zapisanie pliku. Do tego potrzebujemy nowych bibliotek :

#include <QTextStream>
#include <QFile>

A kod wygląda następująco :

      QFile plik1("plik.txt");
       plik1.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
         QTextStream out( & plik1 );
          out <<contents;
       plik1.close();

Wykorzystujemy tutaj strumie danych i dopisujemy do naszego pliku .txt.

Całość wrzucamy  w jedna funkcje np.  void zapisz_tekst(); , którą uruchamiamy przez klikniecie w button „zapisz”.

Czyli kliknij PPM na button -> Przejdz do slotu -> clicked() i wklejamy zapisz_tekst();

W moim przypadku cały kod wygląda następująco :

 

#include "yourself.h"
#include "ui_yourself.h"
# include "autor.h"
#include 
#include
#include 
#include 






YourSelf::YourSelf(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::YourSelf)
{
    ui->setupUi(this);

         otworz_plik();


}

YourSelf::~YourSelf()
{
    delete ui;
}

void YourSelf::on_actionZamknij_triggered()
{
    close();
}

void YourSelf::on_actionAutor_triggered()
{
   autor_info=new autor(this);
   autor_info->show();

   // autor dialog;
}


void YourSelf::otworz_plik(){

    QFile plik("plik.txt");

    plik.open(QIODevice::ReadOnly);


    QString contents = plik.readAll().constData();

     ui->textBrowser->setText(contents);

    plik.close();
    }

 void YourSelf::zapisz_plik(){
     QFile plik("plik.txt");

     plik.open(QIODevice::ReadOnly);


     QString contents = plik.readAll().constData();


     plik.close();


      QString title ;
      title = ui->plainTextEdit_2->toPlainText();
     QString tresc ;
      tresc = ui->plainTextEdit->toPlainText();

      contents= contents+title+tresc;

      QFile plik1("plik.txt");

          plik1.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);

         QTextStream out( & plik1 );
        out <<contents;
          plik1.close();
 }





void YourSelf::on_pushButton_clicked()
{
       zapisz_plik();
}

Odczytywanie i wyświetlanie danych z pliku testowego

Jak odczytać i wyświetlić pliki tekstowe w Qt ? już tłumaczę.

 

Zaczynamy od utworzenia funkcji , która będzie odczytywać i obsługiwać plik tekstowy.

W moim przypadku jest funkcja typu void a jej nazwa : otworz_plik. Funkcja nie przyjmuje żadnych argumentów.

Zapisujemy ją w pliku z rozszerzeniem  .h   w  strefie public . U mnie jest to :

    void otworz_plik();

Do obsługi plików używamy typ QFile nazwiemy go plik  a w argumencie podajemy nazwę i lokalizacje pliku .  ( domyślna lokalizacja jest w katalogu z skompilowanym programem)

QFile plik("plik.txt");

Otwieramy go :

plik.open(QIODevice::ReadOnly);

W argumencie widać że służy tylko do odczytu.
Teraz zapisujemy wszystko do zmiennej string , a jako że to biblioteka Qt to zmienna jest typu Qstring.

QString contents = plik.readAll().constData();

widać że korzystamy z wbudowanej funkcji readAll , zgodnie z nazwą funkcja odczytuje plik tekstowy w całości.
Teraz najważniejszy krok :

ui->textBrowser->setText(contents);

przeczytany tekst zapisujemy w naszym oknie textBrowser , który dodaliśmy projektując główne okno aplikacji.

I kończąc prace z plikiem , zamykamy go :

plik.close();

W całości nasza funkcja wygląda tak :

void YourSelf::otworz_plik(){

    QFile plik("plik.txt");

   plik.open(QIODevice::ReadOnly);

    QString contents = plik.readAll().constData();

     ui->textBrowser->setText(contents);

    plik.close();

    }

Teraz , żeby zauważyć nasz efekt , musimy uruchomić funkcję , wiec dodajemy ja do konstruktora:

 

YourSelf::YourSelf(QWidget *parent) :
 QMainWindow(parent),
 ui(new Ui::YourSelf)
{
 ui->setupUi(this);
 otworz_plik();
}

Komputery nie potrafią dodawać!

O tym jak komputery oszukują i dlaczego jesteś od nich

mądrzejszy!

 

Tak to prawda , komputery wcale nie potrafią dodawać , a Ty jesteś od nich o wiele lepszy !

Stwierdzisz co to za bzdury? A może złamię Twoją wiarę w te piękne , szybkie a jakże głupie urządzenia.

Ok, to była teza.  Teraz  pora na dowód. Nie jestem technicznym poliglotą , więc ograniczmy się do języków.

Dla przykładu , dodaj liczbę 0.2 do 0.3 , hm proste prawda? bo to aż całe 0.5 , nawet jak wklepiemy w google to też tak wyjdzie.

Wrzućmy to w kompilator , np . w C++ :

#include <iostream>

using namespace std;

int main()
{
cout << "Wynik 0.2+0.3 = " << 0.2+0.3 << endl;
return 0;
}

 

Otrzymamy :  Wynik 0.2+0.3=0.5  , ups poległem? Nie do końca , dodajmy bibliotekę  #include<iomanip> i do cout wrzućmy polecenie setprecision(18)  – tłumaczyć polecenia raczej nie muszę.

Kod wygląda następująco :

#include <iostream>
#include<iomanip>

using namespace std;

int main()
{
  cout <<"Wynik dodawania 0.3+0.2 = " <<setprecision(18) << 0.3 + 0.2 << endl;

  return 0;
}

I nagle wynik jest inny , a dokładniej :

Wynik dodawania 0.1+0.2 = 0.500000000000000044

Process returned 0 (0x0) execution time : 0.022 s
Press any key to continue.

Podobnie wygląda dla C# :

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1{

class Program{    

  static void Main(string[] args) {

    Console.WriteLine("{0:R}", .3 + .2);

  Console.ReadKey();

     }
  }
}

 

Odpowiedź mamy jak wyżej  , ale skąd to się bierze?   zagadka?  jakiś żart?

Wyjaśnienie jest proste ,

nasze głupie komputery to urządzenia działające w systemie binarnym, one znają tylko dwie wartości 0 i 1 , o ile konwersja liczb naturalnych jest prosta , bo każdy mająca minimalne pojęcie w tym temacie będzie wiedział że    3  =  011 , a 5 = 101  i tak dalej, ale jak zapisać np,  0.2?

Schemat jest taki mnożysz liczbę razy dwa i jeśli wychodzi równe bądź większe jeden to ją zapisujemy , jeśli mniejsze to zero. Dla przykładu :

  1.  0.2*2 = 0.4            mamy : 0
  2.  0.4*2=0.8              mamy : 00
  3. 0.8*2=1.6               mamy : 001
  4. (1.6-1)*2=1.2         mamy : 0011
  5. (1.2-1)*2=0.4        mamy :  00110

Teraz odczytajmy tą liczbe :     zaczynamy od lewej strony i podnosimy do potęgi z tym, że ujemnej.

Wygląda to tak :

0 0 1 1 0
0*  2^(-1) 0*2^(-2) 1*2^(-3) 1*2^(-4) 0*2^(-5)

Sumujemy wartości w drugim wierszu i mamy : 0·0,5+0·0,25+1·0,125+1·0,0625= =0,1875   , łapiesz?

Dla liczby 0.3 mamy zapis binarny : 01001  czyli w systemie dziesiętnym 0.28125 , jak można zauważyć im dłuższy zapis binarny tym mniejszy błąd zapisu w systemie dziesiętnym, a nie można liczyć w nieskończoność, dlatego komputery po otrzymaniu określonej wartości błędu , lub  z powodu ograniczenia bitów kończy konwersje liczby dziesiętnej na binarnej, potem sumuje  dwie już niedokładne liczby i stąd ta nasza różnica w odpowiedziach programów. Mimo wszystko jak widać , potrzeba aż 17 miejsc po przecinku aby zauważyć błąd :).

 

W podsumowaniu napiszę tylko, że i tak jako  homo sapiens jesteśmy bardziej inteligentni niż te małe skrzyneczki 🙂

Głowa do góry!

PWM – co to ? i jak programiści używali już 30 lat temu

PWM (ang. Pulse-Width Modulation)

– metoda regulacji sygnału prądowego lub napięciowego, o stałej amplitudzie i częstotliwości,
polegająca na zmianie wypełnienia sygnału, używana w zasilaczach impulsowych,
wzmacniaczach impulsowych i układach sterujących pracą silników elektrycznych.

O to na tyle. 

 

A tak na poważnie o co chodzi?  Prostym przykładem wykorzystania PWM  jest generowanie dodatkowych kolorów przez diodę RGB , lub sterowanie serwomechanizmem.

Przedstawię działanie na diodzie.

Generując sygnał prostokątny , bo taki będzie załączać diodę , czyli stan wysoki X świeci ,stan niski brak. Okres cały trwa T.

Wpływając na czas X – poszerzając go lub zwężając  np   , że X to będzie 25% okresu T – to oszukujemy nasz wzrok i wydaję nam się że dioda świeci ciemniej . Ale częstotliwość  f=1/T   musi wynosić powyżej 30Hz – warunek konieczny.

Gdy czas X będzie wynosić 0.6T  ( 60% okresu) to naturalnie dioda będzie świecić jaśniej

Dodatkowo mieszając w ten sposób kolory (ponieważ dioda RGB jak sama nazwa ma tylko 3 kolory : zielony , czerwony , niebieski) uzyskujemy złudzenie dodatkowych kolorów.

Okazuje się, że ludzki wzrok nie jest doskonały i już przy 24 Hz (24 zmianach na sekundę) oko przestaje widzieć kolejne fazy obrazu i uśrednia wynik.

A co ma wspólnego Commodore 64 ( gimby nie znajo ) z PWM ?

Co to te Commodore ? to komputer powstały 1984r. Jego układ oferował fabrycznie zdefiniowaną paletę 16 barw.Podczas grania jednak można było zauważyć więcej kolorów. Wtedy programiści zauważyli , że jeśli szybko zamienisz dwa kolory – powiedzmy o 50 lub 60 klatkach na sekundę – możesz uzyskać  coś, czego nie ma. Na maszynie z szesnastoma kolorami,  można dodać wiele różnych kolorów  do sceny.

 

 

Spróbuj policzyć kolory na powyższym gifie 🙂

 

Dodatkowo na temat kolorów  w Commodore 64 możesz poczytać oraz zobaczyć ciekawe przykłady klikając tutaj

Pierwszy problem rozwiązany ! – łączenie nowego okna do projektu !

O tak ! problem  z yourself.obj rozwiązany

Już myślałem że się pożegnamy! , ale udało się , mała rzecz , bzdurna rzecz a jednak cieszy.

Przez długi czas próbowałem dodać okno autor do głównego projektu.  W kodzie źródłowym nazwaprojektu.cpp załączamy nasze okno czyli na górze wklejamy   #include „autor.h”   I tak jak wcześniej w naszym oknie projektowania klikamy  PPM na dole na Autor i przejdź do slotu ,  w metodzie ( w moim przypadku ) void YourSelf::on_actionAutor_triggered() ,  wklejamy kawałek kodu :

autor_info=new autor(this);
autor_info->show();

I mogłoby się wydawać wszystko pięknie , klikamy Uruchom i co? i error , mniej więcej takie krzaki :

mainwindow.obj:-1: error: LNK2019: unresolved external symbol „public: __cdecl EditStudentDialog::EditStudentDialog(class QWidget *)” (??0EditStudentDialog@@QEAA@PEAVQWidget@@@Z) referenced in function „private: void __cdecl MainWindow::on_actionNew_triggered(void)” (?on_actionNew_triggered@MainWindow@@AEAAXXZ)

mainwindow.obj:-1: error: LNK2019: unresolved external symbol „public: virtual __cdecl EditStudentDialog::~EditStudentDialog(void)” (??1EditStudentDialog@@UEAA@XZ) referenced in function „private: void __cdecl MainWindow::on_actionNew_triggered(void)” (?on_actionNew_triggered@MainWindow@@AEAAXXZ)

i coś tam że brak pliku : YourSelf.obj.  Kilka dni myślenia o co chodzi, oglądania tutków, i w sumie do tej pory nie wiem o co chodzi ale znalazłem rozwiązanie na stackoverflow.com   , cytuję :

Right click on project > Clean

 

Right click on project > Run qmake

 

Right click on project > Build

 

Run – worked first time

 

To znaczy

Z menu z obrazka klikamy kolejno : wyczyść,  Uruchom qmake i odpal. Ta da ! Działa 🙂

Teraz tylko zrobić commit co też jest dla mnie problemem …

 

Ten post pisałem na szybko  , jeśli czegoś nie rozumiesz – daj znać. Chętnie pomogę!

Zespolona transformata Fouriera

Zespolona transformata Fouriera  – co to? po co ? kto to? i co mnie to obchodzi.

       Jean Baptiste Joseph Fourier (1768-1830) – francuski matematyk. Ogromna waga prac i badań zapewniła Fourierowi światową sławę. Jego metody były odkrywcze i oryginalne, a teoria równań zawdzięcza mu wiele istotnych ulepszeń. Fourier pracował m.in. nad teorią ciepła i analizą

Fourier

towarzyszy

Napoleonowi

w wyprawie

do Egiptu, 1798

 

  Wynikiem prac Fouriera nad liczbowymi metodami rozwiązywania równań algebraicznych stała się, wydana już pośmiertnie, Analiza określonych równań (1830). Analiza nazwana jego nazwiskiem przedstawia funkcję okresową jako ciąg parametrów, które, pomnożone przez ustalony z góry ciąg funkcji okresowych, dają daną funkcję.

    Fourier udowodnił, że taka postać musi być zbieżna dla szerokiego zakresu funkcji. Warto zauważyć, że dzięki analizie fourierowskiej istnieją takie urządzenia, jak na przykład: telefon komórkowy, płyta audio CD, odtwarzacz MP3 oraz praktycznie wszystko, co dotyczy fal.

A teraz do rzeczy :

  Transformacja Fouriera jest operatorem liniowym określanym na pewnych przestrzeniach funkcyjnych, elementami których są funkcje n zmiennych rzeczywistych.

   Co to znaczy? Spokojnie , też nie wiem ale wiem że , transformacja Fouriera rozkłada funkcję okresową na szereg funkcji okresowych tak, że uzyskana transformata podaje w jaki sposób poszczególne częstotliwości składają się na pierwotną funkcję.

  To znaczy że  transformata jest to operator matematyczny , który przekształca w funkcję w dziedzinie np. czasu  na dziedzinę częstotliwości. Co jest ważne np. w elektronice – taki prosty przykład to filtry choćby audio. Projektuje się na aby tłumiły w danej częstotliwości , nie w czasie.

Od strony „praktycznej” : 

         Co to mówi?

      Pierwsze równanie  (7a)  mówi  , że zespolona transformata Fouriera w dziedzinie częstotliwości  równa jest ,  całce ( sumom) w danych granicach , z funkcji zależnej od czasu :  f(t)  , pomnożonej /przeskalowanej przez e-j2πft  po dt czy po zmiennej t – funkcji czasu.

Aby z powrotem przekształcić funkcje do pierwotnej postaci stosuję się transformatę odwrotną – wzór 7b

Poniżej przedstawiam przykład zadania. Jest to zespolona transformata Fouriera prostokąta :

 

Jeśli napotkasz jakiś błąd  – daj znać w komentarzu! 🙂

 

źródło :  http://wazniak.mimuw.edu.pl/index.php?title=Biografia_Fourier

Pierwsze okno i GIT

Czas start !

Dziś zrobimy pierwsze okno ! , więc otwieramy Qt creator -> nowy projekt -> Aplikacja -> Aplikacja Qt Widgets.

Dalej wybieramy nazwę projektu oraz klasy. I tu jest ważne aby wpisać odpowiednią nazwę żeby ładnie w górnym pasku się pokazywała!

Następnie po lewej stronie wybieramy Design , a jeśli jest nie aktywny to klikamy na plik :  nazwa.ui

( o w tle widać AVG 🙂 !  )

Teraz w opcji Design możemy pobawić się jak klockami lego, to chyba najprzyjemniejsza część projektowania :), po lewej stronie mamy różne opcje,  warto trochę się nimi pobawić  , coś dodać coś zepsuć , tak żeby zapoznać się z tym bliżej,

Nam do projektu potrzebne będzie kilka podstawowych funkcji : Label , Text Browser , Push Button .

W zależności od opcji na dole po prawej widzimy bardziej zaawansowane ustawienia , możliwość zmiany czcionki , jej wielkości etc

Żeby nasz Text Browser działał tak jak chcemy , to na projekcie należy kliknąć prawym  , następnie przejść do Przekształć w -> QPlanTextEdit

Po kilku minutowym wyklinaniu otrzymujemy coś takiego : 

 

Żeby górne menu było aktywne  , klikamy  na dole w wierszu actionzamknij  zamknij PPM -> Przejdź do slotu -> OK

I dodajemy kawałek kodu :

 

void YourSelf::on_actionZamknij_triggered()
{    
  close();
}

Podobnie robimy z menu Pomoc->autor , z tym że, narazie nie dodamy kodu, a utworzymy nowy Formularz ( na górze po lewej klikamy na folder Formularze PPM -> Dodaj nowy -> Qt -> Klasa formularza Qt Designer -> np. Dialog without Button -> nasza nazwa.

I tam jest piękna rzecz , ponieważ piszemy info o sobie 🙂 , na tym poprzestaniemy , jak tylko uporam się z błędami , powiem co dalej 🙂 ,

Teraz cały projekt ładujemy na GitHub’a , w tym celu instalujemy GIT’a  , ja mam wersje 1.8.4 , nowsza mi z jakiś powodów nie działała.

Klikamy PPM w katalogu gdzie jest nasz projekt i wibieramy GIT Bash , a następnie wklejamy komendy z GitHub’a

Podpisane są następująco :

…or create a new repository on the command line  i brzmią mniej więcej : 

echo "# test" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/david0s/test.git
git push -u origin maste



Gdzie : test – to nazwa projektu.

Copyright nullbyte.pl – programowanie security IT arduino 2018
Tech Nerd theme designed by FixedWidget