Complete Projects

42.1 Console to-do manager with file persistence (Free Pascal)

program Todo;
{$mode objfpc}{$H+}
uses
  SysUtils, Classes;

const
  DataFile = 'todo.txt';

var
  Tasks: TStringList;
  Line, Cmd, Arg: string;
  P, N: Integer;

procedure ListTasks;
var
  I: Integer;
begin
  if Tasks.Count = 0 then
    Writeln('(no tasks)');
  for I := 0 to Tasks.Count - 1 do
    Writeln(I + 1:3, '. ', Tasks[I]);
end;

begin
  Tasks := TStringList.Create;
  try
    if FileExists(DataFile) then
      Tasks.LoadFromFile(DataFile);
    Writeln('Commands: add <text>, list, done <n>, clear, quit');
    repeat
      Write('> ');
      Readln(Line);
      Line := Trim(Line);
      P := Pos(' ', Line);
      if P > 0 then
      begin
        Cmd := LowerCase(Copy(Line, 1, P - 1));
        Arg := Trim(Copy(Line, P + 1, MaxInt));
      end
      else
      begin
        Cmd := LowerCase(Line);
        Arg := '';
      end;
      if Cmd = '' then Continue;

      case Cmd of
        'add':
          if Arg <> '' then
          begin
            Tasks.Add(Arg);
            Writeln('Added #', Tasks.Count);
          end
          else
            Writeln('Nothing to add.');
        'list':
          ListTasks;
        'done':
          if TryStrToInt(Arg, N) and (N >= 1) and 
…

42.2 Word frequency counter (Delphi and FPC {$mode delphi})

program WordFreq;
{$IFDEF FPC}{$mode delphi}{$H+}{$ENDIF}
{$APPTYPE CONSOLE}
uses
  SysUtils, Classes, Math, Generics.Collections;

type
  TWordCount = record
    Word: string;
    Count: Integer;
  end;

var
  Counts: TDictionary<string, Integer>;

procedure AddWord(const S: string);
var
  C: Integer;
begin
  if S = '' then Exit;
  if Counts.TryGetValue(S, C) then
    Counts[S] := C + 1
  else
    Counts.Add(S, 1);
end;

var
  Lines: TStringList;
  Items: array of TWordCount;
  Pair: TPair<string, Integer>;
  Line, W: string;
  I, J, N: Integer;
  Tmp: TWordCount;
begin
  if ParamCount < 1 then
  begin
    Writeln('Usage: wordfreq <textfile>');
    Halt(1);
  end;
  Counts := TDictionary<string, Integer>.Create;
  Lines := TStringList.Create;
  try
    Lines.LoadFromFile(ParamStr(1));
    for Line in Lines do
    begin
      W := '';
      for I := 1 to Length(Line) do
        if CharInSet(Line[I], ['A'..'Z', 'a'..'z', '''']) then
          W := W + LowerCase(Line[I])
        else
        begin
          AddWord(W);
          W := '';
        end;
      AddWord(W);
    end;

    SetLength(Items, Counts.Count);
    N := 0;
    for Pair in Counts do
    begin
      Items[N].Word := 
…

42.3 More project outlines

Lazarus notepad TMemo/TSynEdit (syntax highlighting), TMainMenu, TActionList, open/save dialogs, find/replace dialog, recent files in an INI file, encoding detection Contacts manager

SQLdb or FireDAC + SQLite, TDBGrid, TDBNavigator, search with parameterized queries, CSV import/export Weather dashboard

HTTP client + JSON parsing, background thread or TTask for requests, chart (TAChart in Lazarus, TeeChart in Delphi) REST microservice

Horse or mORMot 2 or fpWeb, JSON endpoints, SQLite storage, unit tests for handlers Mandelbrot explorer

TBitmap scanline drawing, multithreaded rendering by rows, zoom with the mouse, color palettes