• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 180
  • Last Modified:

Problem with numbers...

Hi.

I have some values in a memo from 000 to 999.
Some numbers are missing and some numbers repeat themselfs.
(Example 000,002,002,002,987,524)

I'd like to build a simple chart. In x axis it should be the numbers and in y axis the times they appear.

I cant find a simple way to count the times its number appear and pass it to a chart.
Can you help ?

Thanks in advance :)
0
CodedK
Asked:
CodedK
  • 10
  • 4
  • 2
2 Solutions
 
calinutzCommented:
You should parse the memo and insert all your "numbers" in a table... (any table you like) and then do a SELECT statement like:
select number,count(number) from table group by number

Then just use a DBChart (or if you wish a simple TChart) and use the results of the SQL statement...

Seems like the best and cleanest solution.

Regards
0
 
calinutzCommented:
Of course you could also build a function that also parses the memo.... adds every NEW number to the first column of a 2 column stringgrid (to be more visual... visible) and in the second column place the number of times this number appears. Increase this count everytime you encounter this number. This looks to me like a very slow approach, but hey... it's also doable.


I would still choose the first solution
Regards :-)
0
 
calinutzCommented:
For the first solution here would be the  code for constructing the dataset:

procedure TForm1.Button1Click(Sender: TObject);
var
 i:integer;
 s:string;
begin
for i:=0 to memo1.Lines.Count-1 do
begin
 s := Memo1.Lines[i];
   q1.Active:=false;
   q1.Sql.Clear;
   q1.Sql.Add('insert into table1 (myNumber) values ('+s+')');
   q1.ExecSQL;
end;

ShowMessage('Done inserting');
   q2.Active:=false;
   q2.Sql.Clear;
   q2.Sql.Add('select myNumber,count(MyNumber) from table1 group by myNumber,order by myNumber');
   q2.Active:=true;
ShowMessage('Done the select statement');
end;


After this you just need to set up the Chart.

Regards
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

 
CodedKAuthor Commented:
Calinutz i'd like to take the slow approach. I understand it better :)

BUT
--> adds every NEW number... How?
--> and in the second column place the number of times this number appears... How ?

Theway i was thinging was :

For z:=0 to Memo1.Lines.Count do
begin
 for i:= 0 to 999 do
  begin
   search all the lines for i and increase a variable ... now show the results to a chart (i appears "variable" times)  
  end
end


but the problem is the numbers are like that : (002, not 2 ..... 014 not 14).
0
 
calinutzCommented:
You just need to decide which database to use (try DBDemos or maybe TClientDataset... it's your choice) and decide the field type for MyNumber. And then decide what to use DBChart or TChart . With TDBChart you can construct the Chart directly in designtime using the dataset, and with simple TChart I suggest that you add bars at runtime, one by one (parsing the dataset records ofcourse).

0
 
CodedKAuthor Commented:
:/

Calinutz thanks for the suggestion but i prefare not to work with database at all.
Can you please show me a way (the slow style :) ...)
0
 
calinutzCommented:
Those numbers 002, 014... are not numbers...
they are strings. And you can consider them as strings. Just TRIM the line string so that there will be no added spaces that would confuse the If statement. And then compare the strings
Your choice is not very good i think... It's very very slow.
But if you want it so bad I could help you with it... but only if you insist, since I hate doing slow code :)
0
 
Russell LibbySoftware Engineer, Advisory Commented:
Another way of doing it...

Regards,
Russell

---

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  TeEngine, Series, ExtCtrls, TeeProcs, Chart, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Chart1: TChart;
    Series1: TBarSeries;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
{$R *.DFM}

procedure DataToChart(Lines: TStrings; Series: TChartSeries);
var  lpaData:       Array [0..1000] of Integer;
     dwValue:       Integer;
     dwIndex:       Integer;
begin

  FillChar(lpaData, SizeOf(lpaData), 0);

  Lines.BeginUpdate;
  try
     for dwIndex:=0 to Pred(Lines.Count) do
     begin
        dwValue:=StrToIntDef(Lines[dwIndex], 0);
        Assert((dwValue >= 0) and (dwValue <= 1000), 'Value range check failure!');
        Inc(lpaData[dwValue]);
     end;
  finally
     Lines.EndUpdate;
  end;

  Series.Clear;
  for dwIndex:=0 to 1000 do
  begin
     if (lpaData[dwIndex] > 0) then
     begin
        Series.Add(lpaData[dwIndex], Format('%-.3d', [dwIndex]));
     end;
  end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  DataToChart(Memo1.Lines, Chart1.Series[0]);
end;

end.

-- dfm ---

object Form1: TForm1
  Left = 284
  Top = 114
  Width = 544
  Height = 498
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 12
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Memo1: TMemo
    Left = 96
    Top = 8
    Width = 241
    Height = 173
    Lines.Strings = (
      '000'
      '002'
      '002'
      '002'
      '987'
      '524')
    TabOrder = 1
  end
  object Chart1: TChart
    Left = 96
    Top = 196
    Width = 400
    Height = 250
    BackWall.Brush.Color = clWhite
    BackWall.Brush.Style = bsClear
    Title.Text.Strings = (
      'TChart')
    TabOrder = 2
    object Series1: TBarSeries
      Marks.ArrowLength = 20
      Marks.Visible = True
      SeriesColor = clRed
      XValues.DateTime = False
      XValues.Name = 'X'
      XValues.Multiplier = 1
      XValues.Order = loAscending
      YValues.DateTime = False
      YValues.Name = 'Bar'
      YValues.Multiplier = 1
      YValues.Order = loNone
    end
  end
end


0
 
calinutzCommented:
Done
Follows the DFM and then the pas
0
 
calinutzCommented:
object Form1: TForm1
  Left = 192
  Top = 107
  Width = 720
  Height = 415
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 4
    Top = 360
    Width = 129
    Height = 25
    Caption = 'Calculate chart'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Memo1: TMemo
    Left = 4
    Top = 4
    Width = 253
    Height = 353
    Lines.Strings = (
      '000'
      '001'
      '023'
      '009'
      '001'
      '021'
      '026'
      '021'
      '110'
      '000'
      '000'
      '001'
      '000'
      '002')
    TabOrder = 1
  end
  object Chart1: TChart
    Left = 260
    Top = 4
    Width = 421
    Height = 353
    BackWall.Brush.Color = clWhite
    BackWall.Brush.Style = bsClear
    Title.Text.Strings = (
      'TChart')
    View3D = False
    TabOrder = 2
    object Series1: TBarSeries
      Marks.ArrowLength = 20
      Marks.Style = smsValue
      Marks.Visible = True
      SeriesColor = clRed
      XValues.DateTime = False
      XValues.Name = 'X'
      XValues.Multiplier = 1.000000000000000000
      XValues.Order = loAscending
      YValues.DateTime = False
      YValues.Name = 'Bar'
      YValues.Multiplier = 1.000000000000000000
      YValues.Order = loNone
    end
  end
end
0
 
calinutzCommented:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DB, DBTables, TeEngine, Series, ExtCtrls, TeeProcs,
  Chart;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Chart1: TChart;
    Series1: TBarSeries;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
 i,p,h:integer;
 s,xxx:string;
begin
Chart1.Series[0].Clear;
p:=0;
h:=0;
for i:=0 to memo1.Lines.Count-1 do
begin
  s:=TRIM(memo1.Lines[i]);
  h:=0;
  p:=0;
  repeat
    xxx:=s;
    If TRIM(memo1.Lines[h])=s then p:=p+1;
    h:=h+1;
//    Memo2.Lines.Add(xxx);
  until h=memo1.Lines.Count-1;
  Chart1.Series[0].Add(p,xxx,clGreen);
end;

end;

end.
0
 
CodedKAuthor Commented:
Lol

If this is slow... you should see my codes .... :P

Anyway i'll double the points and split.
Thank you very much Calinutz and Russell.
0
 
calinutzCommented:
In order to see the "numbers" in order you must order the lines of the memo first. Using some of the sorting solutions learned in school :)

Sorry rllibby , I did not refresh the page before posting... but I was doing the code :(
Anyways our solutions are different, so... I guess it's up to CodedK to decide wich one he likes better.

Regards

0
 
calinutzCommented:
Thanks
:)
0
 
CodedKAuthor Commented:
Russells code is faster (and not understable by me :P ) but since you were here from the begining
i accepted yours calinutz. About sorting i've allready did that.
0
 
Russell LibbySoftware Engineer, Advisory Commented:

Thanks for the points..
Btw, my example is actually very simple: when the min/max range is known, and the range is not huge (in this case, only 1000 items), then you can set an array to use as a bucket counter. When a number is read, like 002, then the correspoding bucket [2] is incremented. At the end, the buckets contain a count of each of the items. (no need for multiple passes). Then the array is iterated and the results are put into the chart series.

Russell


0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

  • 10
  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now