Any Insite,, What Am I Not Seeing


Recommended Posts

ok a follow up of the question

here is the code

huskeyw@huskeyw ~/projects/school/statistics $ cat prob2-10.cpp
#include<iostream>
#include <fstream> //file handaling
#include <string> //strings, not sure if I need this
#include<vector> // for c++ containers

using namespace std;

//-----------------------funtions protyping
int check_freq(double file_data, double width , double start_scale,int slots);





//------------------------------main function
int main()
{
double file_data;
vector<int> display (8,0); //vector that holds the output.. type int
double width = .4;
double start_scale = 96.5;
int slots = 7;

ifstream myfile ("test.txt", ios::in); //open file for reading

if (myfile.is_open() )// check if file is open
{
while (! myfile.eof() ) //while not end of file do
{

myfile >> file_data; //write input to Data type double
display [check_freq(file_data,width,start_scale,slots)] += 1; //pass data to check_freq() funtion and return what position of display needs incramented
}
myfile.close();//close file
}
else
cerr <<"Unable to open file" << endl; //error handaling for file open


//---------------------------- temp disply--- needs moved to a funtion or its own headder
for (int y =0; y <=7; y++)
{
cout << display.at(y);
cout << " | ";
}
cout << endl;
return 0;
}
//--------------------------end main funtion
//--------------------------functions

//---------function check_freq, this should be a loop not if statments that incrament the check based on width and slot amounts using min/max
int check_freq (double file_data, double width , double start_scale, int slots)
{
for (int x = 0; x <= slots; x++)
{
cout << "start_scale =: " << start_scale << endl;
cout << "file_data =: " << file_data << endl;
cout << "x =: " << x << endl;
if (file_data >= start_scale && file_data < start_scale + width )
return x;
start_scale += width;
}
return slots;
}
huskeyw@huskeyw ~/projects/school/statistics $

two problems

it is doing one more loop then there is data.. and it is not stepping correctly..

here is the input data

huskeyw@huskeyw ~/projects/school/statistics $ cat test.txt
96.5
96.9
97.3
97.7
98.1
98.5
98.9
99.3

here is the output

huskeyw@huskeyw ~/projects/school/statistics $ ./prob2-10
start_scale =: 96.5
file_data =: 96.5
x =: 0
start_scale =: 96.5
file_data =: 96.9
x =: 0
start_scale =: 96.9
file_data =: 96.9
x =: 1
start_scale =: 96.5
file_data =: 97.3
x =: 0
start_scale =: 96.9
file_data =: 97.3
x =: 1
start_scale =: 96.5
file_data =: 97.7
x =: 0
start_scale =: 96.9
file_data =: 97.7
x =: 1
start_scale =: 97.3
file_data =: 97.7
x =: 2
start_scale =: 96.5
file_data =: 98.1
x =: 0
start_scale =: 96.9
file_data =: 98.1
x =: 1
start_scale =: 97.3
file_data =: 98.1
x =: 2
start_scale =: 97.7
file_data =: 98.1
x =: 3
start_scale =: 96.5
file_data =: 98.5
x =: 0
start_scale =: 96.9
file_data =: 98.5
x =: 1
start_scale =: 97.3
file_data =: 98.5
x =: 2
start_scale =: 97.7
file_data =: 98.5
x =: 3
start_scale =: 98.1
file_data =: 98.5
x =: 4
start_scale =: 96.5
file_data =: 98.9
x =: 0
start_scale =: 96.9
file_data =: 98.9
x =: 1
start_scale =: 97.3
file_data =: 98.9
x =: 2
start_scale =: 97.7
file_data =: 98.9
x =: 3
start_scale =: 98.1
file_data =: 98.9
x =: 4
start_scale =: 98.5
file_data =: 98.9
x =: 5
start_scale =: 96.5
file_data =: 99.3
x =: 0
start_scale =: 96.9
file_data =: 99.3
x =: 1
start_scale =: 97.3
file_data =: 99.3
x =: 2
start_scale =: 97.7
file_data =: 99.3
x =: 3
start_scale =: 98.1
file_data =: 99.3
x =: 4
start_scale =: 98.5
file_data =: 99.3
x =: 5
start_scale =: 98.9
file_data =: 99.3
x =: 6
start_scale =: 96.5
file_data =: 99.3
x =: 0
start_scale =: 96.9
file_data =: 99.3
x =: 1
start_scale =: 97.3
file_data =: 99.3
x =: 2
start_scale =: 97.7
file_data =: 99.3
x =: 3
start_scale =: 98.1
file_data =: 99.3
x =: 4
start_scale =: 98.5
file_data =: 99.3
x =: 5
start_scale =: 98.9
file_data =: 99.3
x =: 6
1 | 2 | 1 | 1 | 1 | 1 | 2 | 0 |

Thanks

Link to post
Share on other sites

Maybe C++ isn't the best language for a quick and dirty little tool like this

brackets.rb

#!/usr/bin/ruby

START = ARGV[0].to_f
BRACKET = ARGV[1].to_f

counts=Array.new()

$stdin.each_line do |line|
i=((line.to_f-START)/BRACKET).to_i

if counts[i].nil?
counts[i]=1
else
counts[i]+=1
end

end

counts.each_index do |i|

puts "[#{i*BRACKET+START}, #{(i+1)*BRACKET+START}) : #{counts[i]}"

end

$ ruby bracket.rb 96.5 0.4 <test.txt
[96.5, 96.9) : 1
[96.9, 97.3) : 2
[97.3, 97.7) :
[97.7, 98.1) : 2
[98.1, 98.5) :
[98.5, 98.9) : 1
[98.9, 99.3) : 2

Link to post
Share on other sites
Maybe C++ isn't the best language for a quick and dirty little tool like this

your probaly right..

Thanks for your answer, and ruby looks like a quick language, but...

I have a c++ class that I am bored in and (teacher is giveing assinemts that take me all of 20 min, unless I miss type something :). I want to learn more.. I have a statistics class that is killing me,, so I figured I would use one(statistics with all of its formulas) to help me learn the other (c++),,, adn give my self harder homework..

well at least for me..

also a note so I can figure out why my loop is not working,,

in this senerio I have 8 slots (if you did a histograph) of a .4 width, so the first number or first bar is 96.5. this bar would represent the amount of times the numers 96.5 - 96.8 appered in the data.. you have 8 slots or bars to represent all the data at a .4 with (96.5,96.6,96.7,96.8 in this case).

so with the data file the out put should be

1 1 1 1 1 1 1 1

or in the above format

96.5, 96.8 : 1

96.9, 97.2 : 1

97.3, 97.6 : 1

97.7, 98.0 : 1

98.1, 98.4 : 1

98.5, 98.8 : 1

98.9, 99.1 : 1

99.2 > : 1

I think its the last one that is killing me.

Link to post
Share on other sites

for (int x = 0; x <= slots; x++)

It's an off by one error. You are starting at 0 and going up to the size of the array, including 0 that's size+1 indicies. The last index of an array is one less than its size.

This is one of those things you need to make habit. You can use "or equal to" tests to control for loops and it may make more sense in a few cases. But you should train yourself to see it as wrong, because usualy it is wrong.

Another problem is that when you detect that the file can't be opened and report an error, you skip some stuff, but still print out some "results". You sould probably return 1; at that point.

Edited by Hai-Etlik
Link to post
Share on other sites
It's an off by one error.

hmmm I thought that also but I have my array at 8 and slots = 7

vector<int> display (8,0);

int slots = 7;

I do have a problem with the width of .4 (I think that should be .3 as the base number is included in the .4 width)

I tried that and its closer but I still have numbers going to the outside.. I think anything after && in the if statment needs removed.. maybe I need to sort the input, I'll try reading the file into a arrray first then parse it.

here is the code so far, I know this should be simple but I am not seeing soem step, maybe I should do a funtion diagram to think better..

#include<iostream>
#include <fstream> //file handaling
#include <string> //strings, not sure if I need this
#include<vector> // for c++ containers

using namespace std;

//-----------------------funtions protyping
int check_freq(double file_data, double width , double start_scale,int slots);





//------------------------------main function
int main()
{
double file_data;
vector<int> display (8,0); //vector that holds the output.. type int
double width = .3;
double start_scale = 96.5;
int slots = 7;

ifstream myfile ("test.txt", ios::in); //open file for reading

if (myfile.is_open() )// check if file is open
{
while (! myfile.eof() ) //while not end of file do
{

myfile >> file_data; //write input to Data type double
display [check_freq(file_data,width,start_scale,slots)] += 1; //pass data to check_freq() funtion and return what position of display needs incramented
}
myfile.close();//close file
}
else
cerr <<"Unable to open file" << endl; //error handaling for file open


//---------------------------- temp disply--- needs moved to a funtion or its own headder
for (int y =0; y <=7; y++)
{
cout << display.at(y);
cout << " | ";
}
cout << endl;
return 0;
}
//--------------------------end main funtion
//--------------------------functions

//---------function check_freq, this should be a loop not if statments that incrament the check based on width and slot amounts using min/max
int check_freq (double file_data, double width , double start_scale, int slots)
{
for (int x = 0; x <= slots; x++)
{
cout << "start_scale =: " << start_scale << endl;
cout << "file_data =: " << file_data << endl;
cout << "x =: " << x << endl;
if (file_data >= start_scale && file_data < start_scale + width )
return x;
else if (file_data > start_scale + width * slots)
return x;
start_scale += width;
}
return 1;
}

also the return 1 just added to slot one in the array?? so I need to change this.. I will move the updating of slots away from the retrun of the function.

Edited by iccaros
Link to post
Share on other sites

With floating point there isn't a next lower number (At least in theory) You don't reduce things by one increment as there isn't sutch an increment. Just because the numbers you happen to be using only go to tenths, doesn't mean that the computer is thinking in tenths.

If you look at my ruby script, you will see that I don't check against each range, I instead convert directly from a number into the array index for that range.

Ruby:

i=((line.to_f-START)/BRACKET).to_i

This takes the value, subtracts the start, then divides by the width.

The result is a floating point number which is 0 at the start of the first range, 1 at the start of the second range, and so on.

It then converts to an integer (truncating the fractional portion) The result of this is an index into an array where the elements represent ranges that include the low bound but not the upper bound, which seems to be what you are after.

Link to post
Share on other sites
With floating point there isn't a next lower number (At least in theory) You don't reduce things by one increment as there isn't sutch an increment. Just because the numbers you happen to be using only go to tenths, doesn't mean that the computer is thinking in tenths.

If you look at my ruby script, you will see that I don't check against each range, I instead convert directly from a number into the array index for that range.

Ruby:

i=((line.to_f-START)/BRACKET).to_i

This takes the value, subtracts the start, then divides by the width.

The result is a floating point number which is 0 at the start of the first range, 1 at the start of the second range, and so on.

It then converts to an integer (truncating the fractional portion) The result of this is an index into an array where the elements represent ranges that include the low bound but not the upper bound, which seems to be what you are after.

thanks .. It took me a few reads but I will try it ( or at least what I think you mean.. Im not that smart..)

I'll report back my finding.. have coding to do.. have a 5 hour flight in three hours...

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...