Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

As an aside, do you mind if I ask how happen to be working in VB6? Is this a legacy application?

rproffitt commented: This was the last year our office would do anything with VB6 apps. Now we'll only talk about migration. +16
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

What exactly are you taking the average of - the rows, the columns, or all of the values together?

Zerrin_1 commented: all of the values together, but I found the answer, thank you +0
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I'll be honest with you, I know very little about statistical analysis and plotting, though I did help someone in this forum with a related plotting issue before.

I did find this article on LOWESS Regression in Python which could help with this aspect of it.

In addition to NumPy and Pandas, that tutorial uses a library called statsmodels, which had an existing implementation of the LOWESS algorithm.

It also uses the Plotly library for rendering the graphs (I was expecting that they would use MatPlotLib, which is widely used for this sort of problem, but presumably there is some advantage to using Plotly - I am not especially familiar with either of them so I can't say). Since I was going to ask how you intended to render the plots, I feel this might be something you need.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Sorry to keep serial posting, but I also noticed the following line:

            'storedquery_id': 'fmi::observations::weather::monthly::simple',

Presumably, there is a form of this parameter which can specify a daily query rather than a monthly one. I don't know enough about the FMI API to determine what that query would be, however, nor where I would find that information.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

The code doesn't do what you think it does. It generates a 3x3 array and then populates it with random values. Frankly, it isn't very good code in general, but the main problem is that it doesn't do what it claims to.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I've done some more experiments, and one of the things I've learned is that FMI only has records for the first day of each month, for some reason. This code will get all of the entries for a period, and when I run it there are only entries for the first of the month. Note that this returns a somewhat different format than that returned by the existing get_monthly_obs() function.

    @classmethod 
    def get_period_obs(cls, place, start_date, end_date, maxlocations=5):
        """
        get multiple observations over a period of dates.

        in:
            place [str]
            start_date [datetime]
            end_date [datetime]
            maxlocations [int] (optional)

        out:
            dictionary with date of the observation,  
            tuple of locations and times keys,
            and dictionary of parameter names and values as strs
            tmon <=> temperature
            rrmon <=> rainfall
        """
        # parameters for the API request
        parms = {
            'request': 'getFeature',
            'storedquery_id': 'fmi::observations::weather::monthly::simple',
            'place':place.lower(),
            'maxlocations':'%d'%maxlocations,
            'starttime': start_date.strftime('%Y-%m-%dT00:00:00'),
            'endtime': end_date.strftime('%Y-%m-%dT00:00:00'),
            }
        parms.update(FmiApi.fixed_params)   # add the fixed parameters to the parameter list       

        # perform the API request
        try:
            resp = requests.get(FmiApi.base_url, params=parms, stream=True)
        except:
            raise Exception('request failed')

        # check the request's status code for errors
        if resp.status_code != 200: raise Exception('FMI returned status code %d'%resp.status_code)

        # parse the raw XML data into an element tree object, exit on failure 
        resp.raw.decode_content=True
        try:
            root = etree.parse(resp.raw)
        except:
            raise Exception('parsing failed')

        # destructure the XML data to get the individual data elements
        members = root.xpath('//wfs:member', namespaces=FmiApi.namespaces)
        weather = {}
        for member in members:
            ptime = member.xpath('.//BsWfs:Time', namespaces=FmiApi.namespaces)[0].text.strip()
            if not ptime in weather:
                weather[ptime] = {}
            ppos = member.xpath('.//gml:pos', namespaces=FmiApi.namespaces)[0].text.strip() …
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I'll post the code I've been working on myself, but I am not sure if it really is going where you want it to. One thing I want to ask about is, would it be better to read the entire dataset for the period being studied rather than repeatedly requesting a large number of days individually?

import datetime
import requests
import lxml.etree as etree
from pprint import pprint
import pickle
import pandas as pd
import numpy as np

class FmiApi:
    """
    a minimalistic wrapper for the Finnish Meteorological Institute API
    """
    base_url = 'http://opendata.fmi.fi/wfs'
    fixed_params = {
        'service': 'WFS',
        'version':'2.0.0',
    }
    namespaces = {
        'wfs':'http://www.opengis.net/wfs/2.0',
        'gml':'http://www.opengis.net/gml/3.2',
        'BsWfs':'http://xml.fmi.fi/schema/wfs/2.0'
    }

    def __init__(self):
        pass

    @classmethod
    def get_daily_obs(cls, place, year, month, day, maxlocations=5):
        """
        get daily simple observation

        in:
            place [str]
            year [int]
            month [int]
            day [int]
            maxlocations [int] (optional)

        out:
            dictionary with tuple of locations and times keys
            and dictionary of parameter names and values as values
            tmon <=> temperature
            rrmon <=> rainfall
        """
        sdate = str(datetime.date(year,month,day)) # current date as a string

        # parameters for the API request
        parms = {
            'request': 'getFeature',
            'storedquery_id': 'fmi::observations::weather::monthly::simple',
            'place':place.lower(),
            'maxlocations':'%d'%maxlocations,
            'starttime': sdate + 'T00:00:00',
            'endtime': sdate + 'T00:00:00',
            }
        parms.update(FmiApi.fixed_params)   # add the fixed parameters to the parameter list

        # perform the API request
        try:
            resp = requests.get(FmiApi.base_url, params=parms, stream=True)
        except:
            raise Exception('request failed')

        # check the request's status code for errors
        if resp.status_code != 200: raise Exception('FMI returned status code %d'%resp.status_code)

        # parse the raw XML data into an element tree object, exit on …
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Is the function pest() in a different source file, or the same one, and in either case, where does it get called?

I did copy the source code (into two separate files, since the FmiAPI only need to run once), and when running pest() I got the following error and traceback:

Traceback (most recent call last):
  File "/home/schol-r-lea/Documents/Programming/Projects/Quick Tests/weather_pest.py", line 66, in <module>
    pest()
  File "/home/schol-r-lea/Documents/Programming/Projects/Quick Tests/weather_pest.py", line 11, in pest
    df_weath = pd.read_csv('wdata.pkl', parse_dates=[0], infer_datetime_format=True)   
  File "/usr/lib/python3.9/site-packages/pandas/util/_decorators.py", line 311, in wrapper
    return func(*args, **kwargs)
  File "/usr/lib/python3.9/site-packages/pandas/io/parsers/readers.py", line 586, in read_csv
    return _read(filepath_or_buffer, kwds)
  File "/usr/lib/python3.9/site-packages/pandas/io/parsers/readers.py", line 482, in _read
    parser = TextFileReader(filepath_or_buffer, **kwds)
  File "/usr/lib/python3.9/site-packages/pandas/io/parsers/readers.py", line 811, in __init__
    self._engine = self._make_engine(self.engine)
  File "/usr/lib/python3.9/site-packages/pandas/io/parsers/readers.py", line 1040, in _make_engine
    return mapping[engine](self.f, **self.options)  # type: ignore[call-arg]
  File "/usr/lib/python3.9/site-packages/pandas/io/parsers/c_parser_wrapper.py", line 69, in __init__
    self._reader = parsers.TextReader(self.handles.handle, **kwds)
  File "pandas/_libs/parsers.pyx", line 542, in pandas._libs.parsers.TextReader.__cinit__
  File "pandas/_libs/parsers.pyx", line 642, in pandas._libs.parsers.TextReader._get_header
  File "pandas/_libs/parsers.pyx", line 843, in pandas._libs.parsers.TextReader._tokenize_rows
  File "pandas/_libs/parsers.pyx", line 1917, in pandas._libs.parsers.raise_parser_error
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte

This seems to indicate a problem in reading the pickled data file. Since you seem to be trying to read the pickled (binary) file as if it were a CSV text file, that's presumably the source of the problem. You presumably want to use pd.read_pickle() rather than pd.read_csv().

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

If you don't mind me asking, how are you running this? I am assuming that you are in a course on assembly language (or at the very least trying to learn from an old textbook), and that you are using DOSBox or something similar, but I am curious about the details. Note that INT 21H is specific to MS-DOS, and modern Windows doesn't support the old software interrupts at all.

As RProffitt said, you would want to read in the input as a pair of characters, then test both of them for their values to see if they are in the desired range.

I also agree on the point of the lack of comments. This is especially important in Assembly language (regardless of the ISA) given the lack of specificity in the individual instructions.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I am no expert on either PHP or MySQL, but I am fairly certain that that won't work, at least as you describe it. You would have to do a separate query to retrieve the value of receiptno for id = 1 first, then increment that value, then use the UPDATE query to set the new value - all while under a single transaction to prevent any hidden race conditions.

However, it also leads to the question of why you are updating the value of receiptno for an existing entry, or perhaps more cogently, why there is a separate receiptno (which is presumably an identifying value) and id (which is presumably a unique, non-data-driven primary key). If receiptno is UNIQUE, then having both is redundant, meaning that the table itself is poorly normalized.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I would recommend copying and pasting the code in the forum using the Code Block (</>) button, rather than posting a screen shot. I get that in this case you wanted to highlight what the editor was telling you, but even so, it is hard for us to work with the code if we only have an image of it.

I don't think it is the name button that is being flagged as invalid, but rather that you are attempting to access an element in a list that doesn't exist (either the list element, nor the list itself).

What you want to do is assign an empty list to button, then use the append method to add the elements to the list.

I'd also mention that, rather than creating list_1 and list_2 and populating them manually without actually using them, you could instead use the range() function. Note that list indices are zero-based, not one-based.

Putting this all together, it would look something like this:

class Buttons(App):
    def build(self):
        button = list()
        for i in range(6):
            elem = BoxLayout(orientation='horizontal'))
            for j in range(10):
                button.append(Button(text='{}{}'.format(elem, j))
                elem.addWidget(button[j])

I can't say for certain that this is what you want, but it seems closer to the intended effect than the original version. I don't know enough about Kivy to say if more needed to be done to make is work as desired. As things stand, it seems like it would create six BoxLayout widgets, populating each with ten Button widgets, but then …

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

If I might be blunt: what idiot taught you to use goto like that?

The goto statement and labels do have some legitimate uses. These are not those. It is an extremely bad idea to use goto indiscriminately like this.

If your instructor has taught an introductory class to use goto at all, you ought to report them to the school administration for incompetence and walk out of the course. Period, end of subject.

Having vented my spleen on this topic now, I would also mention:

  • The lack of decomposition into separate functions.
  • the naming of variables in the form name1, name2, ... nameN, rather than using an array.
rproffitt commented: Good choice of the word decomposition. Over time this code will decompose and smell bad. +16
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Which assembler are you using, and which specific platform (e.g., Raspberry Pi, Apple M1, etc.) is this to run on? While the use of the C library routines makes this generally less important, it is still relevant, as there are differences both in the syntax of specific ARM assemblers, and in how the assembly code interefaces with the library code.

macikayx13 commented: Raspberry PI +0
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Has the course (or any previous ones) discussed sorting algorithms, yet? Given the vagueness of the instructions, something very simple such as Bubble Sort or Gnome Sort should be sufficient, but I know that just saying that won't help much if you haven't studied those before.

As an aside, you would usually place a class into a separate source file, and use a header file to import the class declarations into the main program. If the instructor hasn't covered that topic yet, then it isn't a terribly important in such a straightforward program, but you will want to know about it ahead of time.

You generally also want to avoid using namespace std; in programs generally, but again, that's not really relevant in a homework problem like this - it is just something to keep in mind for the future.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Dumping an assignment to a post without at least saying that is what you are doing isn't the most polite way to start a conversation, especially if you don't show any of your own effort to solve the problem.

It also isn't the safest approach, since plenty of professors regularly search the web to catch students doing things such as this (or more often, they get their TAs and grad students to do it for them).

There are websites where they will do your homework for you, at least for a fee. This isn't one of those sites.

So, try to solve it yourself, and if you get stuck, let us know what you've tried and we'll see if we can help you then. This may be difficult, given the rather minimal and poorly-specified assignment, but it is your assignment, not any of ours.

I will give you one hint, though, in that the problem is really aimed at demonstrating the use of fork(). The solution for the second part, emitting the list of primes, would be trivially solved using the algorithm known as the Sieve of Eratosthenes. Chances are, if you are in a course which covers fork() (usually a Systems Programming or Operating Systems course), then you should already be familiar with the Sieve from previous coursework.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

To elaborate on RProffitt's answer: the error message is saying that you are trying to read the whole array phy rather than a specific (indexed) element of phy. The error is saying that there is no defined cin>> operator for reading an entire array of int. Since this clearly isn't what you were trying to do, the answer RProffitt gave of iterating over the data arrays rather than an array of the marks structure illustrates what you need.

An alternative approach would be to have individual values in the marks struct, and iterate over an array of marks.

#include<iostream>
using namespace std;

struct marks{
    int phy;
    int math;
    int chem;
};

int main(){
    struct marks m[20];
    int i,n;
    cout<<"Enter the number of students : " << endl;
    cin >>n;
    for(i=0;i<n;i++){
        cout<<"\nEnter Physics marks: " << endl;
        cin >> m[i].phy;

        cout<<"\nEnter Maths marks : "<< endl;
        cin >> m[i].math;

        cout<<"\nEnter Chemistry marks : "<< endl;
        cin >> m[i].chem;
    }

    cout<<"\nStudents mark details : \n"<< endl;

    for(i=0;i<n;i++){
         cout<<"\nMarks of Student"<< i+1 <<" : "<< endl;
         cout<<"\nPhysics marks: "<< m[i].phy<< endl;
         cout<<"\nMaths marks: "<< m[i].math<< endl;
         cout<<"\nChemistry marks: "<< m[i].chem<< endl;
         cout<<"\n"<< endl;
    }
    return 0;
}

These two approaches are more or less equivalent; however, you appear to tried to do both at the same time, and got it mixed up as a result.

As a side note: why are you #includeing the conio.h header, a non-standard header which you aren't actually using, and which won't even work under most …

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Dumping an assignment to a post without at least saying that is what you are doing isn't the most polite way to start a conversation, especially if you don't show any of your own effort to solve the problem.

It also isn't the safest approach, since plenty of professors regularly search the web to catch students doing things such as this (or more often, they get their TAs and grad students to do it for them).

There are websites where they will do your homework for you, at least for a fee. This isn't one of those sites.

So, try to solve it yourself, and if you get stuck, let us know what you've tried and we'll see if we can help you then. This may be difficult, given the rather minimal and poorly-specified assignment, but it is your assignment, not any of ours.

rproffitt commented: ++Good. +16
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Actually, I suspect that the opposite is the problem: the object was declared, but never initialized, and thus has a value of Nothing.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

One more possibility (of many) that comes to my mind is that the environment of the cloud server differs from that of the development system, and that there is either some subtle dependency which is lacking, or some added feature on the server which is blocking the script from functioning.

Do you know what sort of system the dev host is, and what sort of system the cloud server runs? If they are (for example) different versions of Windows, or different Linux distributions, that may account for the different behavior.

Similarly, assuming this is a RESTful or otherwise web-based application (which it sounds as if it is), are they using different HTTPS servers for the testing and production servers (e.g., Apache vs. Nginx vs. IIS)? Are there any specific server configs required by the script which the developer neglected to mention, or which you (or the cloud server admin, if that's someone else) may have overlooked?

Also, assuming this is querying a database, how does the test database compare to the production database?

How is the script being tested on the dev host? Is the developer certain that it is being run through the HTTPS server, and not as a purely local script somehow?

Is the script primarily client-side or server-side, or are there separate components for each?

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I did notice that editing the URL only set it to "about:blank", but that doesn't seem to be what you actually were referring to.

razstec commented: i can only get it to open in a new window. my issue is how to make it open in a frame in order to insert it in the interface +3
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Try this instead:

         # force all issues other than "Operations" to "Other"
         if tipo != "Operations":
             tipo = "Other"
razstec commented: it worked like my example, i seems to work fine but the data it sends is incomplete, maybe there was a problem migrating to the cloud server :( +3
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

You've checked the boot order in the BIOS, correct?
Speaking of which, since you mentioned that this is an older system: is it UEFI, or Legacy BIOS?
Also, how did you install Ubuntu originally (assuming it was installed already and that the error message is from the HDD boot)?
Did the error message include any other details beyond the message you already posted?

EDIT: Doing a quick search on the error message, it looks to be a Gnome error rather than a Linux one (which I was wondering about, it was far too casual a message for the Linux kernel). If so, it should be possible to use Ctl-Alt-F2 to get to a shell. You should be able to remove and reinstall Gnome itself in that case.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Sorry for the delay in getting back to you, I'll see what I can find out.

razstec commented: no worrys, this seems a easy one but oddly i can only open in new window and really need it in a frame or something to add to the layout of my project +2
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Just what do you mean by 'changeable'? Does it have to be able to view different websites, rather than the hardcoded one? Or something else?

Also, are you sure you want to be mixing TkInter and Qt like that? I'm not certain that that would really work consistently. If you need the Qt browser tool, I would use Qt for the whole UI.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I'm not sure what you mean by the subtitle, but I am assuming you mean the label for an axis as a whole. For the X axis (horizontal), that would be xlabel, while for the Y axis (vertical) it would be ylabel.

As for the color difference, I was puzzled by that myself. I honestly don't know why it looks different.

One thing I should add is that I wrote it so that it doesn't depend on a fixed number of issue types; if you need to add a new issue type in the future, it should be able to handle it as-is.

razstec commented: but there isnt any ylabel or xlabel in the source :s ill dig in to this tomorow, thanks +2
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

This is as close as I think I can come to the design document. Hope this helps.

import calendar
from math import ceil
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, 
NavigationToolbar2Tk)
from datetime import datetime, timedelta
from dateutil.parser import *
from tkinter import Tk, Button, ttk, Label, CENTER, RIGHT, LEFT, W
from jira import JIRA
import tkinter as tk
import numpy as np
import matplotlib.pyplot as plt
import calendar

class MockProject:
    def __init__(self, name):
        self.name = name

class MockFields:
    def __init__(self, project_name, created_date):
        self.project = MockProject(project_name)
        self.created = created_date

class MockIssue:
    def __init__(self, project_name, created_date):
        self.fields = MockFields(project_name, created_date) 

def get_issues(live=True):
    """ Get a set of JIRA issues for a given time period.
        For testing purposes, it can instead get data from 
        a data file 'sample.txt' and mocking up the JIRA
        issue data structure."""
    jsearch_all_year = list()
    jsearch_current_month = list()
    jsearch_last_month = list()
    if live:
        serverURL = 'https://jira.mob.dev/'
        user = 'user'
        password = 'pass'
        options = {'server': serverURL}
        jira = JIRA(options, basic_auth=(user, password))

        projapesquisar = "(GPD, OP)"
        utlapesquisar = str(["user{}".format(x) for x in range(1, 7)]).replace('[','(').replace(']',')')

        jsearch_current_month = jsearch_by(jira, projapesquisar, utlapesquisar, current_month, dt, start, size)
        jsearch_last_month = jsearch_by(jira, projapesquisar, utlapesquisar, last_month, current_month, start, size)
        jsearch_all_year = jsearch_by(jira, projapesquisar, utlapesquisar, year_start, dt, start, size)
    else:
        file = open("sample.txt")
        data_lines = file.readlines()
        for data_line in data_lines:
            tipo, date = data_line.split('<->')
            tipo = tipo.strip()
            date = date.strip()
            if date == 'Date':
                # skip the first line with the labels fo the columns
                continue
            # create …
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Another function for generating another chart, this time the cumulative operations by month. Note that I haven't figured out how to move the legend yet.

def get_annual_breakdown_chart(root, jsearch, start_date, end_date):
    """ Generates a Matplotlib bar chart window from the list of JIRA issues."""
    if len(jsearch) == 0:
        return
    issue_details = dict()
    colorset = ['blue', 'orange', 'red', 'yellow','magenta', 'green', 'cyan', 'violet', 'purple', 'black', 'white', 'gray']
    labels = list()
    next_month = start_date
    for m in range(0, end_date.month):
        labels.append(next_month.strftime("%b"))
        next_month = next_month.replace(month=next_month.month+1)
    index = np.arange(len(labels))
    issue_types = list()
    monthly_counts = [dict() for x in index] 
    # get the number of issues for each type
    for issue in jsearch:
        tipo = issue.fields.project.name.strip()
        datef = issue.fields.created.strip()
        issue_month = parse(datef).month
        # add type to the list of known issue types
        if tipo not in issue_types:
            issue_types.append(tipo)
            for month in monthly_counts:
                month[tipo] = 0
        # increment the count for the issue type for the given month
        monthly_counts[issue_month-1][tipo] += 1

    fig = Figure(figsize=(6,5))
    bar_height = 0.3
    axes = fig.add_axes([0.1, 0.1, 0.8, 0.7],
                        yticks=(index+(bar_height/len(issue_types))),
                        yticklabels=labels,
                        title='xxx Request yyy since start of {}'.format(start_date.strftime("%B %Y")))
    # flatten the data to a form axes.barh() can use
    data = list()
    for i, issue in enumerate(issue_types):
        data.append(list())
        for month in monthly_counts:
            data[i].append(month[issue])
    bars = list()
    for i in range(len(issue_types)):
        bars.append(axes.barh(index+(bar_height*i), data[i], bar_height, label=issue_types[i]))

    fig.legend()
    return fig 

You can run both of these together with the following code:

    figures = list()
    figures.append(FigureCanvasTkAgg(get_annual_breakdown_chart(frm, jsearch_all_year, year_start, todays_date), master=frm))
    figures.append(FigureCanvasTkAgg(get_summary_chart(frm, jsearch_all_year, year_start), master=frm))
#    figures.append(FigureCanvasTkAgg(get_monthly_chart(frm, jsearch_last_month, last_month), master=frm)
#    figures.append(FigureCanvasTkAgg(get_monthly_chart(frm, jsearch_current_month, current_month), master=frm)

    for i,f in …
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I got the simplest of the three types of chart done, and found a way to incorporate it into the the window as you say you need it.

def get_summary_chart(root, jsearch, start_date):
    """ Generates a Matplotlib bar chart window from the list of JIRA issues."""
    if len(jsearch) == 0:
        return
    issue_details = dict()
    colorset = ['gray', 'blue', 'orange', 'red', 'yellow', 'green', 'cyan', 'violet', 'purple', 'black', 'white']
    labels = ["Total"]   # initialize the list with the one element certain to be present
    # total is known from the size of the issues list
    issue_details["total"] = len(jsearch)
    # get the number of issues for each type
    for issue in jsearch:
        tipo = issue.fields.project.name.strip()
        if tipo not in issue_details.keys():
            labels.append(tipo)
            issue_details[tipo] = 1
        else:
            issue_details[tipo] += 1
    print(labels)
    data = [issue_details[issue_type] for issue_type in issue_details.keys()]
    fig = Figure(figsize=(6,5))
    axes = fig.add_axes([0.1, 0.1, 0.8, 0.8],
                        xticks=range(len(labels)),
                        xticklabels=labels, 
                        title='xxx Request yyy since start of {}'.format(start_date.strftime("%B %Y")))
    bar_width = 0.4
    bars = axes.bar(range(len(issue_details.keys())), data, width=bar_width, color=colorset)
    return fig

This is used as such:

figure = FigureCanvasTkAgg(get_summary_chart(frm, jsearch_all_year, year_start), master=frm)

I am working on the monthly breakdown chart, and figuring out how to place the generated charts somewhere other than the top of the window.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

OK, weird, I'm not sure how it calculated a '6' there. I'll see if I can find a better function for the week of the month.

EDIT: I found several, but they all seem to have one flaw or another. This one looks like the best I've found so far.

def week_number_of_month(date):
    """ Compute which week of the month a given date is in. 
    Taken from the page at
    https://stackoverflow.com/a/34297954/727708."""
    first_day = date.replace(day=1)
    day_of_month = date.day
    if(first_day.weekday() == 6):
         adjusted_dom = (1 + first_day.weekday()) / 7
    else:
         adjusted_dom = day_of_month + first_day.weekday()
    return int(ceil(adjusted_dom/7.0))
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

facepalm OK, according to a comment on the page I got the code for week_number_of_month(), there is a known bug in datetime.datetime().date() which will cause it to return a negative value for certain dates in the last week of the month. I don't know if this is actually the case, but we might be able to see what is happening here if you could add this line just before that, so we can see what the value it is choking on is.

            print(week_number_of_month(issue_date))

This kludge might fix the problem:

def week_number_of_month(date_value):
    """ Compute which week of the month a given date is in. 
    Taken from the page at https://www.mytecbits.com/internet/python/week-number-of-month."""
    ret_date = date_value.isocalendar()[1] - date_value.replace(day=1).isocalendar()[1] + 1
    if ret_date >= 1:
        return ret_date
    else:
        return 5
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

That last part is a UTC time zone offset, which can be parsed with the format substring %z.

issue_date = datetime.strptime(datef, "%Y-%m-%dT%H:%M:%S.%f%z")

I also edited a previous message, but the relevant part is that Dateutil.parser.parse.parse() may be

from dateutil.parser import *
# ...
        issue_date = parse(datef)
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

:( issue_date = datetime.fromisoformat(datef) ValueError: Invalid isoformat string: '2021-07-16T13:13:01.000+0000'

Damn, that's frustrating. You might need to install and use the dateutil, which can parse aribtrary date and time formats. I'll read up on it myself and see if I can find an answer.

from dateutil.parser import *
# ...
        issue_date = parse(datef)
razstec commented: been reading, i think its because of the parse +0
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

OK, I think this should work, replace the previous assignment to issue_date with

issue_date = datetime.fromisoformat(datef)

This assumes that the dates are in ISO format, which I gather they will be.

This documentation page may be of use here.

razstec commented: :( issue_date = datetime.fromisoformat(datef) ValueError: Invalid isoformat string: '2021-07-16T13:13:01.000+0000' +2
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Could you try this, please?

def jsearch_by(jira, projects, users, start_date, end_date, start, size):
    """ Submits a query to the JIRA server and returns the results."""
    source_query = 'project in {projects} AND creator in {users}'.format(projects=projects, users=users)
    date_query = 'AND created >= {start} AND created < {end}'.format(start=start_date.strftime("%Y-%m-01"), end=end_date.strftime("%Y-%m-%d"))
    query = "{}{}".format(source_query, date_query)
    return jira.search_issues(query, start, size)

You'll need to add the jira argument to the calls to jsearch_by() as well. This was an oversight on my part, sorry.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Which RDBMS are you using (MySQL, MS SQL Server, Oracle, SQLite, PostgreSQL, MS Access, etc.)? While SQL is standardized, no RDBMS follows the standard exactly, and most have some extensions to the standard which might affect our answer.

It might also be useful to know if the SQL statements are embedded or command line, and what language they are embedded in if the former.

That having been said, the general form for CREATE TABLE is:

CREATE TABLE table_name(
    column1 datatype,
    column2 datatype,
    column3 datatype,
   .....
   columnN datatype,
   PRIMARY KEY( one or more columns )
);

As for the constraints, well to be honest I'm not sure how you would enforce some of them, at least in standard SQL. The easiest ones would be the PRIMARY KEY and UNIQUE constraints, as those are commonly used in all SQL variants I can think of. However, the syntax for UNIQUE contraints differs from RDBMS to RDBMS. The version most widely used is:

CREATE TABLE foo (
    column int NOT NULL,
     user_id VARCHAR(128) NOT NULL UNIQUE,
    name VARCHAR(100),
    PRIMARY KEY (id)
);

But in MySQL it is this instead:

    CREATE TABLE foo (
        column int NOT NULL,
        user_id VARCHAR(128) NOT NULL,
        name VARCHAR(100),
        PRIMARY KEY (id),  UNIQUE(user_id)
    );

AFAIK, all of them allow you to create named constraints thusly:

  CREATE TABLE foo (
        column int NOT NULL,
        user_id VARCHAR(128) NOT NULL,
   …
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Huh, I don't know why that wasn't showing up for me earlier, but I do see what is happening. I used two keywords in the formatting string, but didn't give the keyword names in the format command. The correct version should be:

 date_query = 'AND created >= {start} AND created < {end}'.format(start=start_date.strftime("%Y-%m-01"), end=end_date.strftime("%Y-%m-%d"))

Sorry about that. I hope it works now.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Actually, I have another question: has your coursework covered classes yet? While you can make an Abstract Data Type using just functions and primitive data types such as integers and lists, in Python 'ADT' is generally synonymous with class (or very nearly so). The solution isn't all that different either way, but it would be slightly easier to do it as a class IMAO.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Sounds fairly straightforward. What have you done so far, and where are you stuck?

There is one question I would ask: can you use NumPy homogenous integer arrays, or do you need ot use default lists?

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Contrary to what I said earlier, I am now posting the most recent modifications to the code. Hope this helps.

from tkinter import *
import calendar
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
from tkinter import Tk, Button, ttk
from jira import JIRA
import numpy as np
import matplotlib.pyplot as plt
import calendar
from datetime import datetime, date


class MockProject:
    def __init__(self, name):
        self.name = name

class MockFields:
    def __init__(self, project_name, created_date):
        self.project = MockProject(project_name)
        self.created = created_date

class MockIssue:
    def __init__(self, project_name, created_date):
        self.fields = MockFields(project_name, created_date) 

def get_issues(live=True):
    """ Get a set of JIRA issues for a given time period.
        For testing purposes, it can instead get data from 
        a data file 'sample.txt' and mocking up the JIRA
        issue data structure."""
    jsearch_all_year = list()
    jsearch_current_month = list()
    jsearch_last_month = list()
    if live:
        serverURL = 'https://jira.mob.dev/'
        user = 'user'
        password = 'pass'
        options = {'server': serverURL}
        jira = JIRA(options, basic_auth=(user, password))

        projapesquisar = "(GPD, OP)"
        utlapesquisar = str(["user{}".format(x) for x in range(1, 7)]).replace('[','(').replace(']',')')

        jsearch_current_month = jsearch_by(projapesquisar, utlapesquisar, current_month, dt, start, size)
        jsearch_last_month = jsearch_by(projapesquisar, utlapesquisar, last_month, current_month, start, size)
        jsearch_all_year = jsearch_by(projapesquisar, utlapesquisar, year_start, dt, start, size)
    else:
        file = open("sample.txt")
        data_lines = file.readlines()
        for data_line in data_lines:
            tipo, date, time = data_line.split()
            tipo = tipo.strip()
            date = date.strip()
            if date == 'Date':
                # skip the first line with the labels fo the columns
                continue
            # create a mocked issue
            issue = MockIssue(tipo, date)
            issue_date = datetime.strptime(date.strip(), '%Y-%m-%d')
            # accumulate issues for previous …
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I've made some additional cleanup changes, but I'll hold off on posting those until I hear back from Razstec about the verison I just posted.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I was able to mock the JIRA issues objects in order to test the code, and got something that actually displays the wekly charts. It doesn't handle the whole year chart correctly, but it does the weekly for a given month. Let me know if this is what you needed or not.

To use it with the live data from the JIRA server, just remove the False from the call to get_issues.

from tkinter import *
import calendar
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
from tkinter import Tk, Button, ttk
from jira import JIRA
import numpy as np
import matplotlib.pyplot as plt
import calendar
from datetime import datetime, date


class MockProject:
    def __init__(self, name):
        self.name = name

class MockFields:
    def __init__(self, project_name, created_date):
        self.project = MockProject(project_name)
        self.created = created_date

class MockIssue:
    def __init__(self, project_name, created_date):
        self.fields = MockFields(project_name, created_date) 


def get_issues(live=True):
    jsearch_all_year = list()
    jsearch_current_month = list()
    jsearch_last_month = list()
    if live:
        serverURL = 'https://jira.mob.dev/'
        user = 'user'
        password = 'pass'
        options = {'server': serverURL}
        jira = JIRA(options, basic_auth=(user, password))
        jsearch_current_month = jsearch_by(projapesquisar, utlapesquisar, current_month, dt, start, size)
        jsearch_last_month = jsearch_by(projapesquisar, utlapesquisar, last_month, current_month, start, size)
        jsearch_all_year = jsearch_by(projapesquisar, utlapesquisar, year_start, dt, start, size)
    else:
        for data_line in data_lines:
            tipo, date, time = data_line.split()
            tipo = tipo.strip()
            date = date.strip()
            if date == 'Date':
                # skip the first line with the labels fo the columns
                continue
            # create a mocked issue
            issue = MockIssue(tipo, date)
            issue_date = datetime.strptime(date.strip(), '%Y-%m-%d')
            # accumulate issues for …
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

The link doesn't work. By going to GitHub, I can see your account, but it isn't showing any public repositories.

This documentation page seems to be the information you are looking for. My own GitHub account is here.

razstec commented: done +2
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

DpSdkOps.dll is apparently a driver for DigitalPersona fingerprint readers. I would get in touch with HID Corp. about it if you can, since they seem to be the developers of the drivers.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

What is the data type of Invoices.notes? Specifically, is it either a BLOB or [VAR]BINARY, rather than [VAR]CHAR or TEXT? I know it is unlikely, but it was something I thought worth asking about.

For that matter, has anyone had a problem printing a TEXT value? That was actually my first thought, since that seemed the most likely type for the value, but I would be surprised if it were the problem.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Why are you planning to do this? What purpose does minimizing the browser serve?

Also, ActiveX has been deprecated for over fifteen years - you shouldn't be using it at all. Internet Explorer 10 and later (circa 2012) dropped support for it,. and neither Firefox nor Chrome ever supported it in the first place AFAIK. No modern browsers support ActiveX.

As for the answer, I doubt that there is a single solution that would work on all or even most browsers.

rproffitt commented: An example was "bitcoin in a web browser so minimize or hide the browser window." +16
jwenting commented: only reason I can think of for hiding a popup from the user is if it runs suspicious code in the background... +16
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

You might also look at this page to see if it applies to you, if you haven't already.

DB12 commented: I am not logging in remotely, I am doing on local mysql instance. Moreover, I had already checked it out. +0
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I gather that you are upgrading an older program from pyMySQL.connect to MySQL/Connector. What version of MySQL are you using, and if it is an older database, is it using the older security model from prior to MySQL 4.1? Going by the official documentation regarding the connection arguments, "MySQL Connector/Python does not support the old, less-secure password protocols of MySQL versions prior to 4.1." I don't personally know what those older protocols entailed, so I can't say what the relevance of it is, but it was something I thought worth pointing out.

Beyond that I would check the troubleshooting page of the MySQL documentation if you haven't done so already.

DB12 commented: MySQL version in 8.0.25 and Python3.8. +0
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Not without a lot more details as to what you want, no. I can't promise we'd be able to with those details, but I can guarantee we can't without them.

I mean, you don't even mention what platform the app is for - while you tagged C, Java, and Windows, the term 'app' generally implies a mobile application, rather than a desktop one.

What is this app supposed to be? What do you want it to do? What should it look like? What language should it be written in? So many questions, no of which you have given us any clues about.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

While I have some other thoughts about how to improve this code, my immediate thought regarding the left/right and up/down movements of the missile is something like so:

                if (y.Left > enemy.Left)
                {
                     y.Left += 10;
                }
                else if (y.Left < enemy.Left)
                {
                     y.Left -= 10;
                }
                else 
                {
                    // no change, stay on course
                }

                if (y.Top < enemy.Top)
                {
                     y.Top += 10;
                }
                else if (y.Top > enemy.Top)
                {
                     y.Top -= 10;
                }
                else 
                {
                    // no change, stay on course
                }
                if ((abs(y.Left - enemy.left) < 5) && (abs(y.Top - enemy.Top) < 5))
                {
                    // impact
                }

I suspect you've tried this already, however.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

The date format in question appears to be from MS Excel, which uses 1899-12-30 for the Date Zero; Excel in turn seems to have taken this from Lotus 1-2-3, back in the day. The page I linked to below opines that it was supposed to be 1900-01-01 but that someone miscalculated when the format was first developed, and Microsoft 'corrected' this by simply resetting the Day Zero.

Anyway, I did find this SO page which addresses at least part of the problem as so:

SELECT DATETIME((49400 * 3600 * 24) - 3014928000, 'unixepoch');

Which converts the Excel date to SQLite's native ISO-8601 subset by way of UNIX Epoch time, but this is more or less equivalent to what you are already doing, and still leaves the question of how to make this conversion inside the SQLite query for a given Excel date.

That page also has the alternate, but more or less equivalent, forumulation:

SELECT DATETIME(( 40074 - 25569) * 86400 , 'unixepoch') AS UNIX_DATE

Which may be more useful, I'm not sure.

Something like this may do it, but I have no way of testing it right now.

CREATE VIEW UsageByDay AS
SELECT DATETIME((day - 25569) * 86400, 'unixepoch') AS date, 
                SUM(data_in+data_out)/1024.0/1024.0 AS total 
  FROM usage 
GROUP BY day 
ORDER BY day DESC;

No idea if this works, sorry.