iccaros Posted January 19, 2006 Report Share Posted January 19, 2006 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++ containersusing namespace std;//-----------------------funtions protypingint check_freq(double file_data, double width , double start_scale,int slots);//------------------------------main functionint 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/maxint 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 problemsit is doing one more loop then there is data.. and it is not stepping correctly..here is the input datahuskeyw@huskeyw ~/projects/school/statistics $ cat test.txt96.596.997.397.798.198.598.999.3here is the output huskeyw@huskeyw ~/projects/school/statistics $ ./prob2-10start_scale =: 96.5file_data =: 96.5x =: 0start_scale =: 96.5file_data =: 96.9x =: 0start_scale =: 96.9file_data =: 96.9x =: 1start_scale =: 96.5file_data =: 97.3x =: 0start_scale =: 96.9file_data =: 97.3x =: 1start_scale =: 96.5file_data =: 97.7x =: 0start_scale =: 96.9file_data =: 97.7x =: 1start_scale =: 97.3file_data =: 97.7x =: 2start_scale =: 96.5file_data =: 98.1x =: 0start_scale =: 96.9file_data =: 98.1x =: 1start_scale =: 97.3file_data =: 98.1x =: 2start_scale =: 97.7file_data =: 98.1x =: 3start_scale =: 96.5file_data =: 98.5x =: 0start_scale =: 96.9file_data =: 98.5x =: 1start_scale =: 97.3file_data =: 98.5x =: 2start_scale =: 97.7file_data =: 98.5x =: 3start_scale =: 98.1file_data =: 98.5x =: 4start_scale =: 96.5file_data =: 98.9x =: 0start_scale =: 96.9file_data =: 98.9x =: 1start_scale =: 97.3file_data =: 98.9x =: 2start_scale =: 97.7file_data =: 98.9x =: 3start_scale =: 98.1file_data =: 98.9x =: 4start_scale =: 98.5file_data =: 98.9x =: 5start_scale =: 96.5file_data =: 99.3x =: 0start_scale =: 96.9file_data =: 99.3x =: 1start_scale =: 97.3file_data =: 99.3x =: 2start_scale =: 97.7file_data =: 99.3x =: 3start_scale =: 98.1file_data =: 99.3x =: 4start_scale =: 98.5file_data =: 99.3x =: 5start_scale =: 98.9file_data =: 99.3x =: 6start_scale =: 96.5file_data =: 99.3x =: 0start_scale =: 96.9file_data =: 99.3x =: 1start_scale =: 97.3file_data =: 99.3x =: 2start_scale =: 97.7file_data =: 99.3x =: 3start_scale =: 98.1file_data =: 99.3x =: 4start_scale =: 98.5file_data =: 99.3x =: 5start_scale =: 98.9file_data =: 99.3x =: 61 | 2 | 1 | 1 | 1 | 1 | 2 | 0 |Thanks Quote Link to post Share on other sites
Hai-Etlik Posted January 19, 2006 Report Share Posted January 19, 2006 Maybe C++ isn't the best language for a quick and dirty little tool like thisbrackets.rb#!/usr/bin/rubySTART = ARGV[0].to_fBRACKET = ARGV[1].to_fcounts=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 endendcounts.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 Quote Link to post Share on other sites
iccaros Posted January 19, 2006 Author Report Share Posted January 19, 2006 Maybe C++ isn't the best language for a quick and dirty little tool like thisyour 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 1or in the above format96.5, 96.8 : 196.9, 97.2 : 197.3, 97.6 : 197.7, 98.0 : 198.1, 98.4 : 198.5, 98.8 : 198.9, 99.1 : 199.2 > : 1I think its the last one that is killing me. Quote Link to post Share on other sites
Hai-Etlik Posted January 19, 2006 Report Share Posted January 19, 2006 (edited) 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 January 19, 2006 by Hai-Etlik Quote Link to post Share on other sites
iccaros Posted January 19, 2006 Author Report Share Posted January 19, 2006 (edited) It's an off by one error.hmmm I thought that also but I have my array at 8 and slots = 7vector<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++ containersusing namespace std;//-----------------------funtions protypingint check_freq(double file_data, double width , double start_scale,int slots);//------------------------------main functionint 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/maxint 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 January 19, 2006 by iccaros Quote Link to post Share on other sites
Hai-Etlik Posted January 20, 2006 Report Share Posted January 20, 2006 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_iThis 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. Quote Link to post Share on other sites
iccaros Posted January 20, 2006 Author Report Share Posted January 20, 2006 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_iThis 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... Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.