Jump to content

iwato

Members
  • Posts

    1,506
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by iwato

  1. BACKGROUND:  The same code does to different things in two different environments neither of which is good.   Another baffling phenomenon that is probably my doing, but I do not understand.

    On my iPhone: the scroll simply does not do its job.  When the hidden <div> is opened the dynamic action is suppose to return the page to a designated position automatically.  It appears, however, to move the page to the save relative position that it was in before the scroll, but now relative to the new <div>.

    On my computer: the automated scroll functions just as intended, but then any manual scrolling thereafter stutters briefly before the page becomes normal.

    You may observe this phenomenon by clicking on the link And, more... after opening to the GC Tutor item from either the navigation bar on the Grammar Captive mainpage or the Grammar Captive subdomain tutor.grammarcaptive.com.

    The CODE

    .click(function() {
        var hm_content = $("#handyman").html();
        $(".hidden_tr").slideToggle(function() {
            $("#replace_td").html(hm_content);
            $('body, html').animate({scrollTop: $('#your_tutor').offset().top},800);
        });
    })

    Roddy

     

  2. Thank you, Ingolme.

    Your observation appears to have been correct.  I changed the code as follows and all is working as it should.

    section#middle #main #gctutor_div #heading #needhelp_flexbox {
        display: flex;
        display: -webkit-flex;
        justify-content: space-between;
        -webkit-justify-content: space-between;
        flex-wrap: wrap;
    }
    
    .needhelp_left {
    	text-align: right;
    	margin: auto;
    }
    
    .needhelp_right {
    	margin: auto;
    	margin-top: 1.5em;
    }

    Roddy

  3. Thank you, Ingolme.  That was helpful, but it did not solve the problem.  The attribute/property is no longer suppressed, but the resulting condition is identical.  When the screen is narrowed no wrapping takes place.  Rather the image moves in front of the text, as the two <div>s appear to converge.

    I had hoped that the when the viewport shrunk the items within the flexbox would realign vertically.  It were as if, the affected div does not understand that the viewport is shrinking. 

    Roddy

  4. BACKGROUND:  I am inserting a div tag into an HTML document via Javascript and for some reason an ultra-specified flexwrap attribute is being suppressed.  Other flexbox attributes contained within the same specification appear.  It is baffling.

     

    CODE:

    section#middle #main #gctutor_div #heading #needhelp_flexbox {
        display: flex;
        display: -webkit-flex;
        justify-content: space-between;
        -webkit-justify-content: space-between;
        flexwrap: wrap;
    }
    
    .needhelp_left {
    	width: 48%;
    	text-align: right;
    }
    
    .needhelp_right {
    	width: 48%;
    }

    THE EXPERIENCE:  You may experience this phenomenon by proceeding to tutor.grammarcaptive.com,  clicking where it says, "Learn to navigate ...", and then narrowing the width of your screen.

    QUESTION:  How does one account for the suppression? And, if possible, correct for it.

    Roddy

  5. BACKGROUND:  I recently install nodejs and npm and downloaded a library call xregexp.js  Then, I discovered what I did not know.  The applications nodejs (node) and npm are primarily designed for server-side Javascript.  Now, I am confused.  In PHP one can simply include or require PHP from another document file and employ it wherever you like that PHP can be used.  When I try to do something similar with xregexp.js I inevitably fail and am told that the script cannot be found.

    Now, I have node and npm installed above my domain folders so that it can be used with all of my domains.  Simply I do not know how to access the modules that I install with npm, and I was hoping to install several more.

    QUESTION:  How does one access node modules that are installed with npm, but reside above the domain folders in which the Javascript that is targeted to employ them resides?

    Roddy

  6. Understand that my database has been spammed.  Examine carefully the count associated with each of the search terms.  You will see that the same numbers are associated with  different terms and that the count for each is quite large.  Notice too, the accent aigue (´) in front of the phrases "person and happiness" and "person and number";  this is not an accident.

    targetList: 141,الدواعيمنفكرةقرامركابتِف,´person and happiness,157,person and happiness,314,´person and number,157,person,157,&quotperson and number&quot,471,subject-verb agreement,157,subject-verb pairs,157,subject-verb,157,podcast,157,Socratic method,157,Sieben Tore,157,Rundbrief,157,monde académique,157,système éducatif,157,langue sécondaire,157,逆転分析,157,構成,157

    Yes, I can cleanse at the point of input, but how do I write the regex for my two examples:

    friend's idea and friends' ideas

    ?

    Though the cleansing issue remains important, the bigger issue is finding a way to stop the reversal of target and count elements in the case of Arabic search words. I have even forcefully reversed the direction of the Arabic list items, but as soon as they are pushed to the list, they revert to the opposite ordering.

    Roddy

  7. Yes and know.  Please match the following results against the included code.

    RESULTS

    listItem:  Array [ "subject-verb pairs", 157 ]
    listItem:  Array [ "subject-verb agreement", 157 ]
    listItem:  Array [ "&quotperson and number&quot", 471 ]
    listItem:  Array [ "person", 157 ]
    listItem:  Array [ "´person and number", 157 ]
    listItem:  Array [ "person and happiness", 314 ]
    listItem:  Array [ "´person and happiness", 157 ]
    listItem:  Array [ 141, "الدواعيمنفكرةقرامركابتِف" ]

    The CODE

    $.each(jsonData, function(key, object) {
        var searchItem = {};
        var strippedStr = '';
        var agex = new RegExp(/[\u0600-\u06ff]|[\u0750-\u077f]|[\ufb50-\ufbc1]|[\ufbd3-\ufd3f]|[\ufd50-\ufd8f]|[\ufd92-\ufdc7]|[\ufe70-\ufefc]|[\uFDF0-\uFDFD]/g);
       var pungex = new RegExp(/(&#\d{3};)|(&\s{4};)/g);
        var pregex = new RegExp(/["\'\;]/g);
        $.each(object, function(name, value) {
            if (name === 'searchKeyword') {
                var nakedArabic = [];
                if (agex.test(value)) {
                    nakedArabic = value.match(agex);
                    searchItem.target = nakedArabic.join('');
                } else {
                var strippedStr = value.replace(pungex, '');
                strippedStr = strippedStr.replace(pregex, '');
                searchItem.target = strippedStr;
                }
            }							
            if (name === 'searchCategory') {
                searchItem.category = value;
            }
            if (name === 'searchResultsCount') {
                searchItem.count = value;
            }
        });
        searchItems.push(searchItem);
    });

    Roddy

  8. Yes,  the agex variable to which the .test() function is applied contains a regular expression. 

    var agex = new RegExp(
    	/[\u0600-\u06ff]
    	|[\u0750-\u077f]
    	|[\ufb50-\ufbc1]
    	|[\ufbd3-\ufd3f]
    	|[\ufd50-\ufd8f]
    	|[\ufd92-\ufdc7]
    	|[\ufe70-\ufefc]
    	|[\uFDF0-\uFDFD]/g
    	);

    This expression is supposed to identify all characters written in Arabic script including numbers, punctuation, and various diacritical markings.  I can do the same for double-byte Japanese as well (not shown below).  This same procedure cannot be used for ASCII, however.  Indeed, I am finding it difficult to remove HTML entities like &#309;  and &quot;.

    When a visitor enters a search term, Matomo appears to use something akin to urlencode( ) before anything is entered into its own database.  When I pull it out I am left with encoded HTML entities that I, generally speaking, do not want (neither encoded, nor decoded).  This said, an apostrophe between words or letters can be meaningful.  Consider for example the following for phrases "my friend's idea", 'my friend's idea', "my friends' ideas",  and  'my friends' ideas'.  Now, all of the single and double quotation marks are encoded identically, but only the following two are desired

    friend's

    friends' ideas

    My gosh I cannot even write the REGEX to successfully eliminate &#309; and &quot.  Compare the following list items with the Arabic item at the bottom.

    listItem:  Array [ "´person and number&#039", 157 ]jquery-1.11.3.min.js%20line%202%20%3E%20eval:107:9
    listItem:  Array [ "person and happiness", 157 ]jquery-1.11.3.min.js%20line%202%20%3E%20eval:107:9
    listItem:  Array [ "´person and happiness&#039", 157 ]jquery-1.11.3.min.js%20line%202%20%3E%20eval:107:9
    listItem:  Array [ "&#039person and happiness&#039", 157 ]jquery-1.11.3.min.js%20line%202%20%3E%20eval:107:9
    listItem:  Array [ 141, "الدواعيمنفكرةقرامركابتِف" ]

    Yes, the Arabic list item does not fall in the proper order, but at least it comes out clean.  The following REGEX that I wrote myself simply does not work.

    var pungex = new RegExp(/(&#\d{3};)|(&\s{4};)/g);

    The CODE

    if (name === 'searchKeyword') {
      var nakedArabic = [];
      var arabicText = '';
      if (agex.test(value)) {
          nakedArabic = value.match(agex);
          searchItem.target = nakedArabic.join('');
      } else {
    	  var strippedStr = value.replace(pungex,'');
    	  searchItem.target = strippedStr;
      }
    }							
  9. OK.  I will try to make the problem easier to understand.  In order to do so, please examine carefully the following code snippet.

    $.each(sourceObj, function(searchPhrase, searchCount) {
        listItem = [searchPhrase, searchCount];
        if (agex.test(searchPhrase)) {
            listItem = listItem.reverse();
        }
        list.push(listItem);
    });

    The phrase agex.test(searchPhrase)  tests whether the value of searchPhrase is in Arabic.   The result appears something like what follows:

    listItem:  Array [ "構成", 157 ]
    listItem:  Array [ "逆転分析", 157 ]
    listItem:  Array [ "langue sécondaire", 157 ]
    listItem:  Array [ "système éducatif", 157 ]
    listItem:  Array [ "monde académique", 157 ]
    listItem:  Array [ "Rundbrief", 157 ]
    listItem:  Array [ "Sieben Tore", 157 ]
    listItem:  Array [ "Socratic method", 157 ]
    listItem:  Array [ "podcast", 157 ]
    listItem:  Array [ "subject-verb", 157 ]
    listItem:  Array [ "subject-verb pairs", 157 ]
    listItem:  Array [ "subject-verb agreement", 157 ]
    listItem:  Array [ 141, "الدواعيمنفكرةقرامركابتِف" ]

    If I do not reverse the order of the item, the corresponding listItem is returned as follows:

    listItem:  Array [ "141, "الدواعيمنفكرةقرامركابتِف ]

    Either way the phrase and count are reverse in the final list and Wordcloud2 fails.

    When the value of searchPhrase is Arabic agex.test(searchPhrase) returns true as expected.

    Roddy

  10. BACKGROUND:  Not only has my website been spammed, but the spam appears to be of a special sort.  It appears that someone has discovered a way to confuse Wordcloud2's interpretation of the input data.  My reason for believing this is my ability to make Wordcloud2 work with data obtained from within different temporal ranges of the same data field.  You can see clearly from the www.grammarcaptive.com mainpage under Visitor Profile/Word Clouds that under normal conditions Wordcloud2 works with all languages. When I open the temporal range to include the spam, however, WordCloud2 fails to render properly.

    In order to make Wordcloud2 function properly it is necessary to create a List.  In the absence of the spam the items of this list appear in the following order.

    targetList: الدواعي من فكرة قرامر كابتِف,1,構成,1,逆転分析,1,langue sécondaire,1,système éducatif,1,monde académique,1,Rundbrief,1,Sieben Tore,1,Socratic method,1,podcast,1,subject-verb,1,subject-verb pairs,1,subject-verb agreement,1,person and number,3,person,1,´person and number,1,person and happiness,2,´person and happiness,1

    In the presence of the spam the list appears as follows:

    targetList: 構成,157,逆転分析,157,langue sécondaire,157,système éducatif,157,monde académique,157,Rundbrief,157,Sieben Tore,157,Socratic method,157,podcast,157,subject-verb,157,subject-verb pairs,157,subject-verb agreement,157,&quotperson and number&quot,471,person,157,´person and number&#039,157,person and happiness,157,´person and happiness&#039,157,&#039person and happiness&#039,157,&#039&#039الدواعي من فكرة قرامر كابتِف,141

    Notice the appearance of the Arabic entries in the two lists.

    1. In the first instance the Arabic appears first.  In the second instance it appears last.
    2. In the first instance the count appears with no HTML entity, in the second it appears with two.

    QUESTION ONE:  How would you go about cleansing the data of the &quot, &#039, and &quotperson before the list is created?  It appears to require some sort of REGEX expression.

    QUESTION TWO:  Where would you cleanse the data?  Before entry, or after retrieval?  Caution:  Cleaning the data upon entry would likely destroy the ability to search phrases.

    Roddy

     

  11. Quote

    If you are applying that to user-supplied input, that's what I'm wondering and that's what I'm asking.

    I am using it in this way: to visualize recorded frequencies for identical search terms, and for recorded frequencies for discovered matches for those terms.

    Quote

    In general, you just need to figure out what business rules you want to use for that

    I could white list registered members, but even these could be abusive.  I have also been thinking of implementing a no-robot captcha clicker.  For this would require only a simple click before initiating a search.  I have read, however, that even these will only constrain the number of abusers -- not eliminate them. 

    Currently, Matomo collects everything.  Whereupon I extract the data from specific fields, and store then in another database.  Whereupon visitors call up the data on demand.  I suppose I could write an algorithm that would examine the redundancy and variety of searches from a single user over time.  My gosh.  Must I reinvent Google all over again?  This is why I installed Matomo in the first place.  In order to avoid having to reinvent the wheel.  My goal is not to outguess my visitors; rather, it is to learn from and teach them.

    How about dual fields in the same database: one temporary and one permanent?  Create an algorithm that scans the temporary field and fill from the result the field that is used to create the respective word clouds?  Still, I would need guidelines for creating the algorithm's parameters.

    Roddy

  12. The term word cloud is very well defined, if you open to the suggested menu item, for there you can see the currently perverted result.  More importantly, how does one go about validating terms that user's make up?  Indeed, the whole purpose of the search engines and accompanying word clouds is to discover what my visitor's want and what they are able to find.  For, in this way I can better serve them, and they can better serve themselves.

    Specifically,

    1. Visitor enter a keyword or phrase in the search box.
    2. A search is made for the keyword or phrase and all fields of a certain kind that contain that word or phrase are returned.
    3. A count is made of the number of matched rows within the relevant fields.
    4. The search keyword or phrase, the count, and an name for the indexed fields is sent to the local Matomo database
    5. The values for the above three variables are then parsed and two word clouds are generated:  one for the number of times that a particular keyword or phrase has been made; and one for the number of times that a match has been found.

    Where would the validation take place in the above scheme of things?  And, what form are you suggesting that it would take?  The only truly secure way, of which I can think, to insure that spamming does not take place is to deny visitors who are not registered member from use of the search procedures.  This, however, appears extreme.

    Roddy

  13. BACKGROUND:  Many months ago I created three custom search engines and two word clouds.  These latter are used to track visitor search interest and Grammar Captive's ability to match it.  Unfortunately, someone is now abusing my search engines and filling those fields of my database set aside to track search input.  The result of this malicious effort is word clouds that no longer perform their task.  While investigating the mess I have realized two important short-comings of my search engines that I must address:

    The Sanitization/Filtering of Search Input -- In order to produce meaningful word clouds I must clean my search input of non-meaningful characters such as ', ", /, [, (, &quot,  etc.   As Further, as my search engines are capable of handling multilingual input, I must be able to handle unwanted characters in a variety of languages.

    Span Prevention - I must be able to prevent visitors from abusing my search engines and thus destroying Grammar Captive's ability to track and analyze true visitor interest.

    I do not see myself as resolving these two problems easily and would be grateful for any advice that would push in in the direction of successful resolution.

    Roddy

    PS.  If you would like to view the damage that has occurred, go to the Grammar Captive website and examine the word clouds found under Visitor Profile/Word Clouds in the navigation bar.

  14. Thank you, JMRKER, for your input.

    The problem was finally resolved using the following .filter( ) function.

    var uniqVals = visitData.filter((obj, index, self) =>
      index === self.findIndex((other) => (
        other.visitorID === obj.visitorID && other.fullDate === obj.fullDate 
      ))
    );

    Roddy

  15. The Data

    var visitData = [
    	{'visitorID':'6b77f74d969f0254','fullDate':'2019/01/01'},
    	{'visitorID':'6b77f74d969f0254','fullDate':'2019/01/01'},
    	{'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'},
    	{'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'},
    	{'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'},
    	{'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'},
    	{'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/04'},
    	{'visitorID':'470b11ecb96f51a8','fullDate':'2019/01/04'},
    	{'visitorID':'470b11ecb96f51a8','fullDate':'2019/01/05'},
    	{'visitorID':'7783172ce39cd663','fullDate':'2019/01/05'},
    	{'visitorID':'1834494d8537012d','fullDate':'2019/01/06'},
    	{'visitorID':'3321037b66164959','fullDate':'2019/01/06'}
    ];

    Alright, I have played with the map function and discovered that the following code displays exactly what I want -- a subset of unique objects.

    Simply I do not know how to convert it into anything useful.

    The Code

    function getUniqAnalysis(inputArr, comp1, comp2) {
      const unique = inputArr.map(function(e) {
        console.log('e[comp1]: ' + e[comp1] + ' e[comp2]: ' + e[comp2]);
      });
    }

    Something Useful

    var somethingUseful = [
    {'visitorID':'6b77f74d969f0254','fullDate':'2019/01/01'},
    {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'},
    {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/04'},
    {'visitorID':'470b11ecb96f51a8','fullDate':'2019/01/04'},
    {'visitorID':'470b11ecb96f51a8','fullDate':'2019/01/05'},
    {'visitorID':'7783172ce39cd663','fullDate':'2019/01/05'},
    {'visitorID':'1834494d8537012d','fullDate':'2019/01/06'},
    {'visitorID':'3321037b66164959','fullDate':'2019/01/06'}
    ];

    Please advise.

    Roddy

     

     

  16. Thank you, SVG, for your explanation of the one property-value pair reduction.  My transformation of the one property-value pair reduction into a dual property-value pair reduction works for objects with three properties, but not two.  Can you explain why?

    Roddy

  17. I have erred.  What worked for objects with three properties does not work for objects with two properties.  I had hoped that my modification would have rendered the following transformation, but it does not.

    Input Array
    Object { visitorID: "6b77f74d969f0254", fullDate: "2019/01/01" }
    Object { visitorID: "6b77f74d969f0254", fullDate: "2019/01/01" }
    Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/03" }
    Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/03" }
    Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/03" }
    Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/03" }
    Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/04" }
    Object { visitorID: "470b11ecb96f51a8", fullDate: "2019/01/04" }
    Object { visitorID: "470b11ecb96f51a8", fullDate: "2019/01/05" }
    Object { visitorID: "7783172ce39cd663", fullDate: "2019/01/05" }
    
    Output Array
    Object { visitorID: "6b77f74d969f0254", fullDate: "2019/01/01" }
    Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/03" }
    Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/04" }
    Object { visitorID: "470b11ecb96f51a8", fullDate: "2019/01/04" }
    Object { visitorID: "470b11ecb96f51a8", fullDate: "2019/01/05" }
    Object { visitorID: "7783172ce39cd663", fullDate: "2019/01/05" }

    I expected the above transformation base on the below transformation

    var dataArr = [
    	{"name":"Steven Smith","country":"England","age":35},
    	{"name":"Hannah Reed","country":"Scottland","age":23},
    	{"name":"Steven Smith","country":"England","age":35},
    	{"name":"Robert Landley","country":"England","age":84},
    	{"name":"Steven Smith","country":"England","age":35},
    	{"name":"Robert Landley","country":"England","age":56}
    ];
    
    var output = [
    	{"name":"Steven Smith","country":"England","age":35},
    	{"name":"Hannah Reed","country":"Scottland","age":23},
    	{"name":"Robert Landley","country":"England","age":84},
    	{"name":"Robert Landley","country":"England","age":56}
    ];

    In both cases I used two variables for comparison.  In the first case, however, there were only two variables to compare.  In the second there was a third variable for which no matching was intended.

    Alas, where have I gone wrong?

    Roddy

     

     

     

  18. BACKGROUND:  I recently discovered the following piece of code on StackOverflow,.  Although it works for a single property comparison, I do not understand it well enough to expand it to cope with multiple properties.

    function getUnique(inputArr, comp) {
      const unique = inputArr.map(e => e[comp]).map((e, i, final) => final.indexOf(e) === i && i).filter(e => inputArr[e]).map(e => inputArr[e]);
      return unique;
    }

    I would like to create a function that would permit the comparison of multiple values on the order of

    function getUnique(inputArr, comp1 [, comp2[, comp3 [...]]]){...}

    Any suggestions?

    At minimum could you help with a better understanding of how it does what it does.  It maps and filters, but in a manner that I do not comprehend easily enough to manipulate.

    Roddy

    PS.  A little experimentation came up with the following solution.

    function getUnique(inputArr, comp1, comp2) {
    	const unique = inputArr.map(e => e[comp1] && e[comp2])
          .map((e, i, final) => final.indexOf(e) === i && i)
          .filter(e => inputArr[e])
          .map(e => inputArr[e]);
    	return unique;
    }

    It achieves my goal, but a little more understanding is still requested.

     

  19. This produces the best, but not the desired, result.  It is fully responsive on both my MacBook and iPhone, except for on the iPhone one must scroll after the page opens and after the position of the phone has changed.  Upon scrolling the map fills its container as it should.

    If I do not resize the container the map over extends it,

    HTML

    <div id='wm_container'>
        ... OTHER STUFF ...
        <div id="vmap"></div>
    </div><!-- end div#wm_container -->

    CSS

    #worldmap_div #wm_container {
    	background-color: #ffffff;
    	margin-top: 3em;
    	margin-bottom: 1em;
    }
    
    #worldmap_div #wm_container #vmap { 
    	width: 513px;
    	height: 342px;
    }

    JAVASCRIPT

    onResize: function() {
        var containerWidth = $(this).parent().width(),
            containerHeight = (containerWidth * (2/3));
        console.log('Parent: ' + $(this).parent().attr('id'));
        $(this).css({
            'width': containerWidth,
            'height': containerHeight
        });
        $(window).find('svg').attr('viewbox', '0 0 513 342');
        console.log('Map Size: ' +  containerWidth + 'x' +  containerHeight);
    }

    Roddy

×
×
  • Create New...