问:
Alternative to the HTML Bold tag
Okay, so I know that in HTML you can use the  tag, but isn't there a "weight=bold" attribute that I can use in the
 tag?

Or is that in CSS, or Javascript?

答:
You can make text or words Bold with using Text tag.

You can also use Text tag

Head tags
,
,
, ... are default bolded tags and make your text Bold by default unless you change their style with CSS

Above tags was available in HTML but if you like to change the style with CSS you can use

```<code>font-weight:bold
</code>```

OwnerDisplayName: Learner

LastEditorDisplayName: Cerebrus

Title: Alternative to the HTML Bold tag

Body:
You can make text or words Bold with using <b>Text</b> tag.

You can also use <strong>Text</strong> tag

Head tags <h1>, <h2>, <h3>, ... are default bolded tags and make your text Bold by default unless you change their style with CSS

Above tags was available in HTML but if you like to change the style with CSS you can use

font-weight:bold


来源: stackexchange

问:
How can I count weekdays only when I am choosing two dates using DirectoryInfo().GetFiles?
I am trying to find a function to use with the DirectoryInfo().GetFiles function to only count weekdays when I am looking for files in a date range.

The only function I found is

```<code>.Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);
</code>```

which is incompatible with fileInfos.Where

```<code>DateTime d1 = DateTime.Now;
d2 = d1.AddDays(FileAgeYounger);
DateTime d3 = DateTime.Now;
d4 = d3.AddDays(FileAgeOlder);

if (subfolders == true &
    FileExtension != null &
    Fileprefix != null &
    FileUseRelativeAgeOlder == true &
    FileUseRelativeAgeYounger == false & CountWeekDays == true)
{
    FileInfo[] fileInfos = new DirectoryInfo(FolderLocation).GetFiles("*.*", SearchOption.AllDirectories);
    IEnumerable<FileInfo> files = fileInfos.Where((f) => f.Extension.Equals(FileExtension)
                                                      && f.Name.StartsWith(Fileprefix)
                                                      && f.CreationTime >= d3
                                                      && f.CreationTime <= d4);
}
</code>```

答:
In this code...

.Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);
```

<p>...<code>x</code> is a <code>FileInfo</code>, which doesn't have a <code>DayOfWeek</code> property.  Instead, you need to use whichever of the three <code>*Time</code> properties of <code>FileInfo</code> is appropriate; looking at the condition you passed to <code>.Where()</code> that appears to be <code>CreationTime</code>...</p>

<pre class="lang-cs prettyprint-override"><code>int count = files.Count(x => x.CreationTime.DayOfWeek != DayOfWeek.Saturday && x.CreationTime.DayOfWeek != DayOfWeek.Sunday);
</code>```

Alternatively, that code could be made to work by using .Select() to retrieve just the desired *Time property...

int count = files
    .Select(f => f.CreationTime)
    .Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);
```

In this case, x is a DateTime.

Also, keep in mind the differences between the older GetFiles() method and the newer EnumerateFiles() method...

The EnumerateFiles and GetFiles methods differ as follows:

When you use EnumerateFiles, you can start enumerating the collection of FileInfo objects before the whole collection is returned.

When you use GetFiles, you must wait for the whole array of FileInfo objects to be returned before you can access the array.

Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient.

EnumerateFiles() is well-suited for this kind of filesystem search/filtering, and, I think, generally the preferred method to use.

ContentLicense: CC BY-SA 4.0

Body:
I am trying to find a function to use with the DirectoryInfo().GetFiles function to only count weekdays when I am looking for files in a date range.

The only function I found is

.Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);

which is incompatible with fileInfos.Where

DateTime d1 = DateTime.Now;
d2 = d1.AddDays(FileAgeYounger);
DateTime d3 = DateTime.Now;
d4 = d3.AddDays(FileAgeOlder);

if (subfolders == true &
    FileExtension != null &
    Fileprefix != null &
    FileUseRelativeAgeOlder == true &
    FileUseRelativeAgeYounger == false & CountWeekDays == true)
{
    FileInfo[] fileInfos = new DirectoryInfo(FolderLocation).GetFiles("*.*", SearchOption.AllDirectories);
    IEnumerable<FileInfo> files = fileInfos.Where((f) => f.Extension.Equals(FileExtension)
                                                      && f.Name.StartsWith(Fileprefix)
                                                      && f.CreationTime >= d3
                                                      && f.CreationTime <= d4);
}

Body:
In this code...

.Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);

...x is a FileInfo, which doesn't have a DayOfWeek property.  Instead, you need to use whichever of the three *Time properties of FileInfo is appropriate; looking at the condition you passed to .Where() that appears to be CreationTime...

int count = files.Count(x => x.CreationTime.DayOfWeek != DayOfWeek.Saturday && x.CreationTime.DayOfWeek != DayOfWeek.Sunday);

Alternatively, that code could be made to work by using .Select() to retrieve just the desired *Time property...

int count = files
    .Select(f => f.CreationTime)
    .Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);

In this case, x is a DateTime.

Also, keep in mind the differences between the older GetFiles() method and the newer EnumerateFiles() method...

The EnumerateFiles and GetFiles methods differ as follows:

When you use EnumerateFiles, you can start enumerating the collection of FileInfo objects before the whole collection is returned.

When you use GetFiles, you must wait for the whole array of FileInfo objects to be returned before you can access the array.

Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient.

EnumerateFiles() is well-suited for this kind of filesystem search/filtering, and, I think, generally the preferred method to use.


问:
How solve ImportError: No module named 'dbus'?
I have installed anaconda4 on my ubuntu and I have these modules on my Python:

```<code>dbus-python (1.2.4)

gi (1.2)

pydbus (0.2)

QtAwesome (0.3.2)
qtconsole (4.2.0)
QtPy (1.0)

sip (4.18)
</code>```

I tried installing dbus-python (1.2.4) and pydbus (0.2), however, neither of them works!

After testing a simple program in python 3.5.1, an error appeared:

```<code>import dbus
system_bus = dbus.SystemBus()

ImportError: No module named 'dbus'
</code>```

When I use pydbus in Python 2.7.11 and 3.5.1:

```<code>from pydbus import SystemBus

bus = SystemBus()
systemd = bus.get(".systemd1")

for unit in systemd.ListUnits():
    print(unit)
</code>```

I get this error:

```<code>ImportError: No module named repository
</code>```

The only thing that works is this example with PyQT4 which I don't have any tutorial for.

What is the problem? Is it my installation or something else?

答: Try re-installing dbus-python. Also try on another virtual environment.</p>

ContentLicense: CC BY-SA 3.0

Body:
I have installed anaconda4 on my ubuntu and I have these modules on my Python:

dbus-python (1.2.4)

gi (1.2)

pydbus (0.2)

QtAwesome (0.3.2)
qtconsole (4.2.0)
QtPy (1.0)

sip (4.18)

I tried installing dbus-python (1.2.4) and pydbus (0.2), however, neither of them works!

After testing a simple program in python 3.5.1, an error appeared:

import dbus
system_bus = dbus.SystemBus()

ImportError: No module named 'dbus'

When I use pydbus in Python 2.7.11 and 3.5.1:

from pydbus import SystemBus

bus = SystemBus()
systemd = bus.get(".systemd1")

for unit in systemd.ListUnits():
    print(unit)

I get this error:

ImportError: No module named repository

The only thing that works is this example with PyQT4 which I don't have any tutorial for.

What is the problem? Is it my installation or something else?


问:
Next() is not being called on beforeRouteUpdate using the same component
I am using the same vue-component to display data that I'm fetching with axios. After clicking on a link the ajax-request is fetching new data.

But if the component is already loaded and the user clicks another link to load different data, the next()-method is not called.

Check out my codepen to see what I mean. There should be an alert showing. If you click a link for the first time, it does. If you switch to another link, it does not.

https://codepen.io/spqrinc/pen/YzXGGGL

答:
From the docs:

Note that beforeRouteEnter is the only guard that supports passing a callback to next. For beforeRouteUpdate and beforeRouteLeave, this is already available, so passing a callback is unnecessary and therefore not supported

So the next() in beforeRouteUpdate can't take a callback because you already have access to the instance in this.  Anything you would have done with vm in that callback can be done without it using this:

```<code>beforeRouteUpdate(to, from, next) {
  alert("Reloaded");
  // `this` works
  next();
}
</code>```

Body:
From the docs:

Note that beforeRouteEnter is the only guard that supports passing a callback to next. For beforeRouteUpdate and beforeRouteLeave, this is already available, so passing a callback is unnecessary and therefore not supported

So the next() in beforeRouteUpdate can't take a callback because you already have access to the instance in this.  Anything you would have done with vm in that callback can be done without it using this:

beforeRouteUpdate(to, from, next) {
  alert("Reloaded");
  // `this` works
  next();
}


问:
documentation for Kaggle API *within* python?
I want to write a python script that downloads a public dataset from Kaggle.com.

The Kaggle API is written in python, but almost all of the documentation and resources that I can find are on how to use the API in command line, and very little on how to use the kaggle library within python.

Some users seem to know how to do this, see for example several answers to this question, but the hints are not enough to resolve my specific issue.

Namely, I have a script that looks like this:

```<code>from kaggle.api.kaggle_api_extended import KaggleApi

api = KaggleApi('content of my json metadata file')

file = api.datasets_download_file(
    owner_slug='the-owner-slug',
    dataset_slug='the-dataset-slug',
    file_name='the-file-name.csv',
)
</code>```

I have come up with this by looking at the method's signature:

api.datasets_download_file(owner_slug, dataset_slug, file_name, **kwargs)

I get the following error:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa1 in position 12: invalid start byte

Beyond the solution to this specific problem, I would be really happy to know how to go about troubleshooting errors with the Kaggle library, other than going through the code itself.  In fact, perhaps the issue has nothing to do with utf-encoding, but I don't know how to figure this out.  What if it is just that the filename is wrong, or something as silly as this?

The csv file is nothing special:  three columns, first is timestamp, the other two are integers.

答:
I published a blog post that explains most of the common use cases of competition, datasets and kernel interactions.

Here are the steps involved in using the Kaggle API from within Python.

Setting up API Key

Go to your Kaggle account Tab at https://www.kaggle.com/<username>/account
and click ‘Create API Token’.  A file named kaggle.json will be downloaded. Move this file in to ~/.kaggle/ folder in Mac and Linux or to C:\Users<username>.kaggle\  on windows.

Alternatively, you can populate KAGGLE_USERNAME and KAGGLE_KEY environment variables with values from kaggle.json to get the api to authenticate.

Authenticating With API Server

```<code>from kaggle.api.kaggle_api_extended import KaggleApi
api = KaggleApi()
api.authenticate()
</code>```

Downloading Datasets

```<code># Download all files of a dataset
# Signature: dataset_download_files(dataset, path=None, force=False, quiet=True, unzip=False)
api.dataset_download_files('avenn98/world-of-warcraft-demographics')

# download single file
#Signature: dataset_download_file(dataset, file_name, path=None, force=False, quiet=True)
api.dataset_download_file('avenn98/world-of-warcraft-demographics','WoW Demographics.csv')
</code>```

Downloading Competition Files

```<code># Download all files for a competition
# Signature: competition_download_files(competition, path=None, force=False, quiet=True)
api.competition_download_files('titanic')

# Download single file for a competition
# Signature: competition_download_file(competition, file_name, path=None, force=False, quiet=False)
api.competition_download_file('titanic','gender_submission.csv')
</code>```

Submitting to competitions

```<code># Signature: competition_submit(file_name, message, competition,quiet=False)
api.competition_submit('gender_submission.csv','API Submission','titanic')
</code>```

Retrieving Leader Board

```<code># Signature: competition_view_leaderboard(id, **kwargs)
leaderboard = api.competition_view_leaderboard('titanic')
</code>```

Body:
I want to write a python script that downloads a public dataset from Kaggle.com.

The Kaggle API is written in python, but almost all of the documentation and resources that I can find are on how to use the API in command line, and very little on how to use the kaggle library within python.

Some users seem to know how to do this, see for example several answers to this question, but the hints are not enough to resolve my specific issue.

Namely, I have a script that looks like this:

from kaggle.api.kaggle_api_extended import KaggleApi

api = KaggleApi('content of my json metadata file')

file = api.datasets_download_file(
    owner_slug='the-owner-slug',
    dataset_slug='the-dataset-slug',
    file_name='the-file-name.csv',
)

I have come up with this by looking at the method's signature:

api.datasets_download_file(owner_slug, dataset_slug, file_name, **kwargs)

I get the following error:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa1 in position 12: invalid start byte

Beyond the solution to this specific problem, I would be really happy to know how to go about troubleshooting errors with the Kaggle library, other than going through the code itself.  In fact, perhaps the issue has nothing to do with utf-encoding, but I don't know how to figure this out.  What if it is just that the filename is wrong, or something as silly as this?

The csv file is nothing special:  three columns, first is timestamp, the other two are integers.

Body:
I published a blog post that explains most of the common use cases of competition, datasets and kernel interactions.

Here are the steps involved in using the Kaggle API from within Python.

Setting up API Key

Go to your Kaggle account Tab at https://www.kaggle.com/<username>/account
and click ‘Create API Token’.  A file named kaggle.json will be downloaded. Move this file in to ~/.kaggle/ folder in Mac and Linux or to C:\Users<username>.kaggle\  on windows.

Alternatively, you can populate KAGGLE_USERNAME and KAGGLE_KEY environment variables with values from kaggle.json to get the api to authenticate.

Authenticating With API Server

from kaggle.api.kaggle_api_extended import KaggleApi
api = KaggleApi()
api.authenticate()

Downloading Datasets

# Download all files of a dataset
# Signature: dataset_download_files(dataset, path=None, force=False, quiet=True, unzip=False)
api.dataset_download_files('avenn98/world-of-warcraft-demographics')

# download single file
#Signature: dataset_download_file(dataset, file_name, path=None, force=False, quiet=True)
api.dataset_download_file('avenn98/world-of-warcraft-demographics','WoW Demographics.csv')

Downloading Competition Files

# Download all files for a competition
# Signature: competition_download_files(competition, path=None, force=False, quiet=True)
api.competition_download_files('titanic')

# Download single file for a competition
# Signature: competition_download_file(competition, file_name, path=None, force=False, quiet=False)
api.competition_download_file('titanic','gender_submission.csv')

Submitting to competitions

# Signature: competition_submit(file_name, message, competition,quiet=False)
api.competition_submit('gender_submission.csv','API Submission','titanic')

Retrieving Leader Board

# Signature: competition_view_leaderboard(id, **kwargs)
leaderboard = api.competition_view_leaderboard('titanic')


问:
R : Returning a value from loop when manually stopping it
I am trying to build a database with rvest. Since I have much data to download, I tried to write several functions that would allow me to interrupt the scraping process and to restart it where I left it. However, while the functions work more or less, whenever I manually interrupt them, I loose the output. Does anyone know a solution that would allow me to stop the function without loosing the dataframe that the loop is building ? I would be glad for any advice!

Some urls that I am trying to scrape data from:

```<code>to_do <- c("https://jobs.51job.com/shenzhen-nsq/116924235.html?s=01&t=0",
          "https://jobs.51job.com/shenzhen-nsq/116923692.html?s=01&t=0",
          "https://jobs.51job.com/shenzhen-nsq/116923628.html?s=01&t=0",
          "https://jobs.51job.com/shenzhen-nsq/116923578.html?s=01&t=0",
          "https://jobs.51job.com/shenzhen-nsq/116920896.html?s=01&t=0")
</code>```

The functions I created for downloading:

```<code># In order to initiate the dowload
dl_data_start <- function(to_do){
  output <- tibble()
  i = 1
  while (to_do[i] %in% to_do) {
      page <- read_html(to_do[i])
      position <- page %>%
        html_nodes(.,'h1') %>%
        html_text(.)
      resume <- page %>%
        html_nodes(.,'.ltype') %>%
        html_text(.)
      job_offer <- page %>%
        html_nodes(.,'.job_msg') %>%
        html_text(.)
      eps <- page %>%
        html_nodes(.,'.com_msg') %>%
        html_text(.)
      eps_status <- page %>%
        html_nodes(.,'.at:nth-child(1)') %>%
        html_text(.)
      eps_description <- page %>%
        html_nodes(.,'.tmsg') %>%
        html_text(.)
      employees <- page %>%
        html_nodes(.,'.at:nth-child(2)') %>%
        html_text(.)
      category <- page %>%
        html_nodes(.,'.at:nth-child(3)') %>%
        html_text(.)
      salary <- page %>%
        html_nodes(.,'.cn strong') %>%
        html_text(.)
      url <- to_do[i]
      id <- i
      current <- tibble(position,resume,job_offer,eps,eps_description,eps_status,
                        employees,category,salary,url,id)
      output <- bind_rows(output,current)
      print(output[i,])
      i = i + 1
  }
  return(output)
}
</code>```

```<code># function in order to continue the download where I left it
dl_data_continue <- function(to_do,df,done){
  i = (match(tail(done,n=1),to_do) + 1)
  while (to_do[i] %in% to_do) {
    page <- read_html(to_do[i])
    position <- page %>%
      html_nodes(.,'h1') %>%
      html_text(.)
    resume <- page %>%
      html_nodes(.,'.ltype') %>%
      html_text(.)
    job_offer <- page %>%
      html_nodes(.,'.job_msg') %>%
      html_text(.)
    eps <- page %>%
      html_nodes(.,'.com_msg') %>%
      html_text(.)
    eps_status <- page %>%
      html_nodes(.,'.at:nth-child(1)') %>%
      html_text(.)
    eps_description <- page %>%
      html_nodes(.,'.tmsg') %>%
      html_text(.)
    employees <- page %>%
      html_nodes(.,'.at:nth-child(2)') %>%
      html_text(.)
    category <- page %>%
      html_nodes(.,'.at:nth-child(3)') %>%
      html_text(.)
    salary <- page %>%
      html_nodes(.,'.cn strong') %>%
      html_text(.)
    url <- to_do[i]
    id <- i
    current <- tibble(position,resume,job_offer,eps,eps_description,eps_status,
                      employees,category,salary,url,id)
    df <- bind_rows(df,current)
    print(df[i,])
    i = i + 1
  }
  return(df)
}
</code>```

The issue I have is that whenever an I interrupt the loop or when an error occurs, I loose all the data. Could anybody solve this problem ? I tried several things such as safely or tryCatch but I can't get my head around what's wrong here.
Thank you very much.

Edit :
I also made some attemps with tryCatch. Using the below function, the code no longer breaks whenever it encounters a problem (e.g. HTTP 404 error). However when there's an error, the loop will remain stuck in the problematic iteration, so I must use it wrong.

```<code>dl_data_continue_2 <- function(to_do,df,done){
  i = (match(tail(done,n=1),to_do) + 1)
  while (to_do[i] %in% to_do) {
    tryCatch(
      {expr =
        page <- read_html(to_do[i])
      position <- page %>%
        html_nodes(.,'h1') %>%
        html_text(.)
      resume <- page %>%
        html_nodes(.,'.ltype') %>%
        html_text(.)
      job_offer <- page %>%
        html_nodes(.,'.job_msg') %>%
        html_text(.)
      eps <- page %>%
        html_nodes(.,'.com_msg') %>%
        html_text(.)
      eps_status <- page %>%
        html_nodes(.,'.at:nth-child(1)') %>%
        html_text(.)
      eps_description <- page %>%
        html_nodes(.,'.tmsg') %>%
        html_text(.)
      employees <- page %>%
        html_nodes(.,'.at:nth-child(2)') %>%
        html_text(.)
      category <- page %>%
        html_nodes(.,'.at:nth-child(3)') %>%
        html_text(.)
      salary <- page %>%
        html_nodes(.,'.cn strong') %>%
        html_text(.)
      url <- to_do[i]
      id <- i
      current <- tibble(position,resume,job_offer,eps,eps_description,eps_status,
                        employees,category,salary,url,id)
      df <- bind_rows(df,current)
      print(df[i,])
      i = i + 1},
      error = function(e){
        message("* Caught an error on itertion ")
        print(e)
        i = i + 1
      }
    )
  }
  out
}
</code>```

Using safely, I basically tried

```<code>library(purrr)
dl_safely <- safely(dl_data_continue)
</code>```

答:
I come across this problem often in webscraping. The key is to store the intermediate results in an environment where they are accessible if your function throws an error. The obvious place is the global environment, but this depends on how you are using your function. If it is part of a package, then you don't want to write to the global workspace. In that case you can have a "storage" environment as part of the package.

Perhaps the neatest way to do this is to delete the intermediate object after the loop is complete, so it will only ever be visible / accessible if the loop throws an error.

Here is a function that demonstrates the principle:

write_data_frames <- function(n)
{
  if(!exists("temporary", .GlobalEnv))
  {
    assign("temporary", list(), envir = globalenv())
    i <- 1
  }
  else
  {
    i <- length(.GlobalEnv$temporary) + 1
  }

  while(i <= n)
  {
    # This is the block where you do your web scraping and store the result
    .GlobalEnv$temporary[[i]] <- data.frame(var1 = rnorm(1), var2 = runif(1))

    # We'll create an error when i == 4
    if(i == 4) stop("Something broke!")
    i <- i + 1
  }
  result <- do.call(rbind, temporary)
  rm("temporary", envir = globalenv())
  return(result)
}
```

<p>Now, this should return a nice data frame if I ask it for 3 rows:</p>

```write_data_frames(3)
#>         var1      var2
#> 1 -1.6428100 0.1976913
#> 2  0.7136643 0.9684348
#> 3 -0.4845004 0.0294557
```

<p>And it hasn't left anything in our global workspace:</p>

```ls()
#> [1] "write_data_frames"
```

<p>But suppose I ask for ten rows: here, it will throw an error on the fourth loop:</p>

```write_data_frames(10)
#> Error in write_data_frames(10) : Something broke!
```

<p>However, this time, the object <code>temporary</code> is available to me:</p>

```ls()
#> [1] "temporary"         "write_data_frames"

temporary
#> [[1]]
#>       var1      var2
#> 1 -1.46648 0.1748874
#>
#> [[2]]
#>          var1      var2
#> 1 -0.03855686 0.5772731
#>
#> [[3]]
#>        var1      var2
#> 1 0.8228591 0.4115181
#>
#> [[4]]
#>        var1      var2
#> 1 0.9183934 0.2732575
```

<p>Even better, my function is designed to just carry on from where it left off, so if I once again do</p>

```write_data_frames(10)
#>           var1      var2
#> 1  -1.46647987 0.1748874
#> 2  -0.03855686 0.5772731
#> 3   0.82285907 0.4115181
#> 4   0.91839339 0.2732575
#> 5   0.54850658 0.9946303
#> 6  -1.39917426 0.9948544
#> 7   0.39525152 0.9234611
#> 8  -1.05899076 0.6226182
#> 9  -2.03137464 0.1218762
#> 10  0.24880216 0.6631982
```

<p>The function has started again from position 5 without any modification. And now, when we check our global workspace, there's nothing left:</p>

```ls()
#> [1] "write_data_frames"
```

Body:
I am trying to build a database with rvest. Since I have much data to download, I tried to write several functions that would allow me to interrupt the scraping process and to restart it where I left it. However, while the functions work more or less, whenever I manually interrupt them, I loose the output. Does anyone know a solution that would allow me to stop the function without loosing the dataframe that the loop is building ? I would be glad for any advice!

Some urls that I am trying to scrape data from:

to_do <- c("https://jobs.51job.com/shenzhen-nsq/116924235.html?s=01&t=0",
          "https://jobs.51job.com/shenzhen-nsq/116923692.html?s=01&t=0",
          "https://jobs.51job.com/shenzhen-nsq/116923628.html?s=01&t=0",
          "https://jobs.51job.com/shenzhen-nsq/116923578.html?s=01&t=0",
          "https://jobs.51job.com/shenzhen-nsq/116920896.html?s=01&t=0")

The functions I created for downloading:

# In order to initiate the dowload
dl_data_start <- function(to_do){
  output <- tibble()
  i = 1
  while (to_do[i] %in% to_do) {
      page <- read_html(to_do[i])
      position <- page %>%
        html_nodes(.,'h1') %>%
        html_text(.)
      resume <- page %>%
        html_nodes(.,'.ltype') %>%
        html_text(.)
      job_offer <- page %>%
        html_nodes(.,'.job_msg') %>%
        html_text(.)
      eps <- page %>%
        html_nodes(.,'.com_msg') %>%
        html_text(.)
      eps_status <- page %>%
        html_nodes(.,'.at:nth-child(1)') %>%
        html_text(.)
      eps_description <- page %>%
        html_nodes(.,'.tmsg') %>%
        html_text(.)
      employees <- page %>%
        html_nodes(.,'.at:nth-child(2)') %>%
        html_text(.)
      category <- page %>%
        html_nodes(.,'.at:nth-child(3)') %>%
        html_text(.)
      salary <- page %>%
        html_nodes(.,'.cn strong') %>%
        html_text(.)
      url <- to_do[i]
      id <- i
      current <- tibble(position,resume,job_offer,eps,eps_description,eps_status,
                        employees,category,salary,url,id)
      output <- bind_rows(output,current)
      print(output[i,])
      i = i + 1
  }
  return(output)
}

# function in order to continue the download where I left it
dl_data_continue <- function(to_do,df,done){
  i = (match(tail(done,n=1),to_do) + 1)
  while (to_do[i] %in% to_do) {
    page <- read_html(to_do[i])
    position <- page %>%
      html_nodes(.,'h1') %>%
      html_text(.)
    resume <- page %>%
      html_nodes(.,'.ltype') %>%
      html_text(.)
    job_offer <- page %>%
      html_nodes(.,'.job_msg') %>%
      html_text(.)
    eps <- page %>%
      html_nodes(.,'.com_msg') %>%
      html_text(.)
    eps_status <- page %>%
      html_nodes(.,'.at:nth-child(1)') %>%
      html_text(.)
    eps_description <- page %>%
      html_nodes(.,'.tmsg') %>%
      html_text(.)
    employees <- page %>%
      html_nodes(.,'.at:nth-child(2)') %>%
      html_text(.)
    category <- page %>%
      html_nodes(.,'.at:nth-child(3)') %>%
      html_text(.)
    salary <- page %>%
      html_nodes(.,'.cn strong') %>%
      html_text(.)
    url <- to_do[i]
    id <- i
    current <- tibble(position,resume,job_offer,eps,eps_description,eps_status,
                      employees,category,salary,url,id)
    df <- bind_rows(df,current)
    print(df[i,])
    i = i + 1
  }
  return(df)
}

The issue I have is that whenever an I interrupt the loop or when an error occurs, I loose all the data. Could anybody solve this problem ? I tried several things such as safely or tryCatch but I can't get my head around what's wrong here.
Thank you very much.

Edit :
I also made some attemps with tryCatch. Using the below function, the code no longer breaks whenever it encounters a problem (e.g. HTTP 404 error). However when there's an error, the loop will remain stuck in the problematic iteration, so I must use it wrong.

dl_data_continue_2 <- function(to_do,df,done){
  i = (match(tail(done,n=1),to_do) + 1)
  while (to_do[i] %in% to_do) {
    tryCatch(
      {expr =
        page <- read_html(to_do[i])
      position <- page %>%
        html_nodes(.,'h1') %>%
        html_text(.)
      resume <- page %>%
        html_nodes(.,'.ltype') %>%
        html_text(.)
      job_offer <- page %>%
        html_nodes(.,'.job_msg') %>%
        html_text(.)
      eps <- page %>%
        html_nodes(.,'.com_msg') %>%
        html_text(.)
      eps_status <- page %>%
        html_nodes(.,'.at:nth-child(1)') %>%
        html_text(.)
      eps_description <- page %>%
        html_nodes(.,'.tmsg') %>%
        html_text(.)
      employees <- page %>%
        html_nodes(.,'.at:nth-child(2)') %>%
        html_text(.)
      category <- page %>%
        html_nodes(.,'.at:nth-child(3)') %>%
        html_text(.)
      salary <- page %>%
        html_nodes(.,'.cn strong') %>%
        html_text(.)
      url <- to_do[i]
      id <- i
      current <- tibble(position,resume,job_offer,eps,eps_description,eps_status,
                        employees,category,salary,url,id)
      df <- bind_rows(df,current)
      print(df[i,])
      i = i + 1},
      error = function(e){
        message("* Caught an error on itertion ")
        print(e)
        i = i + 1
      }
    )
  }
  out
}

Using safely, I basically tried

library(purrr)
dl_safely <- safely(dl_data_continue)

Body:
I come across this problem often in webscraping. The key is to store the intermediate results in an environment where they are accessible if your function throws an error. The obvious place is the global environment, but this depends on how you are using your function. If it is part of a package, then you don't want to write to the global workspace. In that case you can have a "storage" environment as part of the package.

Perhaps the neatest way to do this is to delete the intermediate object after the loop is complete, so it will only ever be visible / accessible if the loop throws an error.

Here is a function that demonstrates the principle:

write_data_frames <- function(n)
{
  if(!exists("temporary", .GlobalEnv))
  {
    assign("temporary", list(), envir = globalenv())
    i <- 1
  }
  else
  {
    i <- length(.GlobalEnv$temporary) + 1
  }

  while(i <= n)
  {
    # This is the block where you do your web scraping and store the result
    .GlobalEnv$temporary[[i]] <- data.frame(var1 = rnorm(1), var2 = runif(1))

    # We'll create an error when i == 4
    if(i == 4) stop("Something broke!")
    i <- i + 1
  }
  result <- do.call(rbind, temporary)
  rm("temporary", envir = globalenv())
  return(result)
}

Now, this should return a nice data frame if I ask it for 3 rows:

write_data_frames(3)
#>         var1      var2
#> 1 -1.6428100 0.1976913
#> 2  0.7136643 0.9684348
#> 3 -0.4845004 0.0294557

And it hasn't left anything in our global workspace:

ls()
#> [1] "write_data_frames"

But suppose I ask for ten rows: here, it will throw an error on the fourth loop:

write_data_frames(10)
#> Error in write_data_frames(10) : Something broke!

However, this time, the object temporary is available to me:

ls()
#> [1] "temporary"         "write_data_frames"

temporary
#> [[1]]
#>       var1      var2
#> 1 -1.46648 0.1748874
#>
#> [[2]]
#>          var1      var2
#> 1 -0.03855686 0.5772731
#>
#> [[3]]
#>        var1      var2
#> 1 0.8228591 0.4115181
#>
#> [[4]]
#>        var1      var2
#> 1 0.9183934 0.2732575

Even better, my function is designed to just carry on from where it left off, so if I once again do

write_data_frames(10)
#>           var1      var2
#> 1  -1.46647987 0.1748874
#> 2  -0.03855686 0.5772731
#> 3   0.82285907 0.4115181
#> 4   0.91839339 0.2732575
#> 5   0.54850658 0.9946303
#> 6  -1.39917426 0.9948544
#> 7   0.39525152 0.9234611
#> 8  -1.05899076 0.6226182
#> 9  -2.03137464 0.1218762
#> 10  0.24880216 0.6631982

The function has started again from position 5 without any modification. And now, when we check our global workspace, there's nothing left:

ls()
#> [1] "write_data_frames"


问:
Why are my data elements being copied instead of moved?
I'm performing some tests about move semantics, and my class behavior seems weird for me.

Given the mock class VecOfInt:

```<code>class VecOfInt {
public:
    VecOfInt(size_t num) : m_size(num), m_data(new int[m_size]) {}
    ~VecOfInt() { delete[] m_data; }
    VecOfInt(VecOfInt const& other) : m_size(other.m_size),  m_data(new int[m_size]) {
        std::cout << "copy..." <<std::endl;
        std::copy(other.m_data, other.m_data + m_size, m_data);
    }
    VecOfInt(VecOfInt&& other) : m_size(other.m_size) {
        std::cout << "move..." << std::endl;
        m_data = other.m_data;
        other.m_data = nullptr;
    }
    VecOfInt& operator=(VecOfInt const& other) {
        std::cout << "copy assignment..." << std::endl;
        m_size = other.m_size;
        delete m_data;
        m_data = nullptr;
        m_data = new int[m_size];
        m_data = other.m_data;
        return *this;
    }
    VecOfInt& operator=(VecOfInt&& other) {
        std::cout << "move assignment..." << std::endl;
        m_size = other.m_size;
        m_data = other.m_data;
        other.m_data = nullptr;
        return *this;
    }
private:
    size_t m_size;
    int* m_data;
};
</code>```

OK CASE

When I insert a single value in-place:

```<code>int main() {
    std::vector<VecOfInt> v;
    v.push_back(10);
    return 0;
}
</code>```

Then it gives me the following output (what I think is fine):

move...

WEIRD CASE

When I insert three different values in-place:

```<code>int main() {
    std::vector<VecOfInt> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    return 0;
}
</code>```

Then the output calls the copy constructor 3 times:

move...
move...
copy...
move...
copy...
copy...

What I'm missing here?

答:
std::vector allocates a block of contiguous memory for its elements. When the allocated memory is too short for storing new elements, a new block is allocated and all current elements are copied from the old block to the new block.

You can use std::vector::reserve() to pre-size the capacity of the std::vector memory before adding new elements.

Try the following:

int main() {
    std::vector<VecOfInt> v;
    v.reserve(3);
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    return 0;
}
```

<p>and you will get:</p>

```move...
move...
move...
```

<p>But to get move constructor being called even when reallocating you should make it <code>noexcept</code> like:</p>

<pre class="lang-cpp prettyprint-override"><code>VecOfInt(VecOfInt&& other) noexcept {...}
</code>```

Body:
I'm performing some tests about move semantics, and my class behavior seems weird for me.

Given the mock class VecOfInt:

class VecOfInt {
public:
    VecOfInt(size_t num) : m_size(num), m_data(new int[m_size]) {}
    ~VecOfInt() { delete[] m_data; }
    VecOfInt(VecOfInt const& other) : m_size(other.m_size),  m_data(new int[m_size]) {
        std::cout << "copy..." <<std::endl;
        std::copy(other.m_data, other.m_data + m_size, m_data);
    }
    VecOfInt(VecOfInt&& other) : m_size(other.m_size) {
        std::cout << "move..." << std::endl;
        m_data = other.m_data;
        other.m_data = nullptr;
    }
    VecOfInt& operator=(VecOfInt const& other) {
        std::cout << "copy assignment..." << std::endl;
        m_size = other.m_size;
        delete m_data;
        m_data = nullptr;
        m_data = new int[m_size];
        m_data = other.m_data;
        return *this;
    }
    VecOfInt& operator=(VecOfInt&& other) {
        std::cout << "move assignment..." << std::endl;
        m_size = other.m_size;
        m_data = other.m_data;
        other.m_data = nullptr;
        return *this;
    }
private:
    size_t m_size;
    int* m_data;
};

OK CASE

When I insert a single value in-place:

int main() {
    std::vector<VecOfInt> v;
    v.push_back(10);
    return 0;
}

Then it gives me the following output (what I think is fine):

move...

WEIRD CASE

When I insert three different values in-place:

int main() {
    std::vector<VecOfInt> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    return 0;
}

Then the output calls the copy constructor 3 times:

move...
move...
copy...
move...
copy...
copy...

What I'm missing here?

Body:
std::vector allocates a block of contiguous memory for its elements. When the allocated memory is too short for storing new elements, a new block is allocated and all current elements are copied from the old block to the new block.

You can use std::vector::reserve() to pre-size the capacity of the std::vector memory before adding new elements.

Try the following:

int main() {
    std::vector<VecOfInt> v;
    v.reserve(3);
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    return 0;
}

and you will get:

move...
move...
move...

But to get move constructor being called even when reallocating you should make it noexcept like:

VecOfInt(VecOfInt&& other) noexcept {...}


问:
postgres pull out multiple values in a JSON array
I have a table where one of the columns is a JSON array. for each key there are multiple values.

So I use this query to select out the JSON

```<code>select  x.cola eventid, x.colb
from special_event_conflicts t
cross join lateral json_each(t.eventid) as x(cola, colb)
</code>```

which produces

```<code>"525947";"{"f1":133,"f2":2428,"f3":"MULTILINESTRING((1013339.30779158 180228.160778359,1013395.51179424 180119.844273224))"}"
</code>```

what I want is to be able to select out the f1,f2,f3 values into there own columns

答:
Click: demo:db<>fiddle

The most simple way is using the ->> operator:

```<code>SELECT
    x.event_id,
    x.colb ->> 'f1' as f1,
    x.colb ->> 'f2' as f2,
    x.colb ->> 'f3' as f3
FROM <YOUR QUERY>
</code>```

Body:
I have a table where one of the columns is a JSON array. for each key there are multiple values.

So I use this query to select out the JSON

select  x.cola eventid, x.colb
from special_event_conflicts t
cross join lateral json_each(t.eventid) as x(cola, colb)

which produces

"525947";"{"f1":133,"f2":2428,"f3":"MULTILINESTRING((1013339.30779158 180228.160778359,1013395.51179424 180119.844273224))"}"

what I want is to be able to select out the f1,f2,f3 values into there own columns

Body:
Click: demo:db<>fiddle

The most simple way is using the ->> operator:

SELECT
    x.event_id,
    x.colb ->> 'f1' as f1,
    x.colb ->> 'f2' as f2,
    x.colb ->> 'f3' as f3
FROM <YOUR QUERY>


问:
Insert Property List plist in UML
I programmed an IPhone app, and I have to design the UML now. (I know wrong order)

Question: Are the Property Lists, where I save my data designed in UML or not? And if so, how are they connected, association, aggregation,...?

example:

```<code>NSString *path=[documentsDirectory stringByAppendingPathComponent:@"ArticleData.plist"];
NSMutableDictionary *data=[[[NSMutableDictionary alloc] initWithContentsOfFile:path]autorelease];
...
[data setObject:articleId forKey@"id"];
...
[data writeToFile:path atomically:YES];
...
</code>```

Thanks in advance.

答: You don't have iphone compatible UML tool. </p>

Title: Insert Property List plist in UML

Body:
I programmed an IPhone app, and I have to design the UML now. (I know wrong order)

Question: Are the Property Lists, where I save my data designed in UML or not? And if so, how are they connected, association, aggregation,...?

example:

NSString *path=[documentsDirectory stringByAppendingPathComponent:@"ArticleData.plist"];
NSMutableDictionary *data=[[[NSMutableDictionary alloc] initWithContentsOfFile:path]autorelease];
...
[data setObject:articleId forKey@"id"];
...
[data writeToFile:path atomically:YES];
...

Thanks in advance.


问:
Parse different timestamp formats in spark
I have a csv file where some columns are timestamps with this format 'dd/MM/yyyy HH:mm:ss' and other columns in the same .csv file where the timestamp format is 'dd-MM-yyyy HH:mm:ss'.
On spark read csv file I tried something like this:

  SparkSession spark = SparkSession
                .Builder()
                .AppName("Spark Project")
                .GetOrCreate();

                spark.Read()
               .Option("delimiter", fileconfig.FileLoaderColumnSeparator)
               .Option("header", hasHeader)
               .Option("inferSchema", true)
               .Option("TimeStampFormat", "dd/MM/yyyy HH:mm:ss")
               .Option("TimeStampFormat", "dd-MM-yyyy HH:mm:ss")
               .Option("TreatEmptyValuesAsNulls", true)
               .Option("IgnoreLeadingWhiteSpace", true)
               .Option("IgnoreTrailingWhiteSpace", true)
               .Csv(path);
```

But in this way it only assumes as a timestamp the last TimestampFormat and the first one as string.
I also tried to do .Option("TimeStampFormat", "dd-MM-yyyy HH:mm:ss", "dd/MM/yyyy HH:mm:ss") and .Option("TimeStampFormat", "dd-MM-yyyy HH:mm:ss, dd/MM/yyyy HH:mm:ss") but none of this options worked.
How can I parse this two types of timestampformats.

If I omit the option timestampformat all timestamps are saved as strings

答:
It's not possible to specify two timestamp formats while reading csv file, default last timestamp format will be used everything else will be overwritten.

These are the possible options I could think of:

1.use withColumn while reading the csv file:

```<code>import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._

spark.read().
    option("delimiter", fileconfig.FileLoaderColumnSeparator).
    option("header", hasHeader).
    option("inferSchema", true).
    option("TimeStampFormat", "dd-MM-yyyy HH:mm:ss").
    option("TreatEmptyValuesAsNulls", true).
    option("IgnoreLeadingWhiteSpace", true).
    option("IgnoreTrailingWhiteSpace", true).
    csv(path).
    withColumn("<MM/dd/yyyy_field_name>",to_timestamp(col("<MM/dd/yyyy_field_name>","MM/dd/yyyy HH:mm:ss"))
</code>```

read the csv file with one timestamp format:

```<code>val df= spark.read().
    option("delimiter", fileconfig.FileLoaderColumnSeparator).
    option("header", hasHeader).
    option("inferSchema", true).
    option("TimeStampFormat", "dd-MM-yyyy HH:mm:ss").
    option("TreatEmptyValuesAsNulls", true).
    option("IgnoreLeadingWhiteSpace", true).
    option("IgnoreTrailingWhiteSpace", true).
    csv(path)
</code>```

2.Then using to_timestamp function change type to string to timestamp:

from spark >= 2.2

```<code>df.withColumn("<MM/dd/yyyy_field_name>",to_timestamp(col("<MM/dd/yyyy_field_name>","MM/dd/yyyy HH:mm:ss"))
</code>```

3.Using from_unixtime and unix_timestamp functions:

```<code>df.withColumn("<MM/dd/yyyy_field_name>",from_unixtime(unix_timestamp(col("<MM/dd/yyyy_field_name>"),"dd/MM/yyyy HH:mm:ss"),"yyyy-MM-dd HH:mm:ss").cast("timestamp"))
</code>```

4.Using unix_timestamp and casting to timestamp type:

```<code>df.withColumn("<MM/dd/yyyy_field_name>",unix_timestamp(col("<MM/dd/yyyy_field_name>"),"dd/MM/yyyy HH:mm:ss").cast("timestamp"))
</code>```

More dynamic way:

```<code>#input dataframe
df.show()
+-------------------+-------------------+-------------------+
|                 dt|                st1|                dt1|
+-------------------+-------------------+-------------------+
|12/12/2019 09:23:23|12/12/2019 09:23:23|12/12/2019 09:23:23|
|12/13/2018 12:23:23|12/13/2018 12:23:23|12/13/2018 12:23:23|
+-------------------+-------------------+-------------------+
#filter all matching rows starts with dt and cast to timestamp

val df2= df.columns.filter(_.startsWith("dt")).foldLeft(df)((df, c) => {
  df.withColumn(s"$c",unix_timestamp(col(s"$c"),"dd/MM/yyyy HH:mm:ss").cast("timestamp"))
})

df2.show(false)

#dynamically changed the format and casted to timestamp for dt,dt1 columns.
//+---------------------+-------------------+---------------------+
//|dt                   |st1                |dt1                  |
//+---------------------+-------------------+---------------------+
//|2019-12-12 09:23:23.0|12/12/2019 09:23:23|2019-12-12 09:23:23.0|
//|2019-01-12 12:23:23.0|12/13/2018 12:23:23|2019-01-12 12:23:23.0|
//+---------------------+-------------------+---------------------+
</code>```

Body:
I have a csv file where some columns are timestamps with this format 'dd/MM/yyyy HH:mm:ss' and other columns in the same .csv file where the timestamp format is 'dd-MM-yyyy HH:mm:ss'.
On spark read csv file I tried something like this:

  SparkSession spark = SparkSession
                .Builder()
                .AppName("Spark Project")
                .GetOrCreate();

                spark.Read()
               .Option("delimiter", fileconfig.FileLoaderColumnSeparator)
               .Option("header", hasHeader)
               .Option("inferSchema", true)
               .Option("TimeStampFormat", "dd/MM/yyyy HH:mm:ss")
               .Option("TimeStampFormat", "dd-MM-yyyy HH:mm:ss")
               .Option("TreatEmptyValuesAsNulls", true)
               .Option("IgnoreLeadingWhiteSpace", true)
               .Option("IgnoreTrailingWhiteSpace", true)
               .Csv(path);

But in this way it only assumes as a timestamp the last TimestampFormat and the first one as string.
I also tried to do .Option("TimeStampFormat", "dd-MM-yyyy HH:mm:ss", "dd/MM/yyyy HH:mm:ss") and .Option("TimeStampFormat", "dd-MM-yyyy HH:mm:ss, dd/MM/yyyy HH:mm:ss") but none of this options worked.
How can I parse this two types of timestampformats.

If I omit the option timestampformat all timestamps are saved as strings

Body:
It's not possible to specify two timestamp formats while reading csv file, default last timestamp format will be used everything else will be overwritten.

These are the possible options I could think of:

1.use withColumn while reading the csv file:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._

spark.read().
    option("delimiter", fileconfig.FileLoaderColumnSeparator).
    option("header", hasHeader).
    option("inferSchema", true).
    option("TimeStampFormat", "dd-MM-yyyy HH:mm:ss").
    option("TreatEmptyValuesAsNulls", true).
    option("IgnoreLeadingWhiteSpace", true).
    option("IgnoreTrailingWhiteSpace", true).
    csv(path).
    withColumn("<MM/dd/yyyy_field_name>",to_timestamp(col("<MM/dd/yyyy_field_name>","MM/dd/yyyy HH:mm:ss"))

read the csv file with one timestamp format:

val df= spark.read().
    option("delimiter", fileconfig.FileLoaderColumnSeparator).
    option("header", hasHeader).
    option("inferSchema", true).
    option("TimeStampFormat", "dd-MM-yyyy HH:mm:ss").
    option("TreatEmptyValuesAsNulls", true).
    option("IgnoreLeadingWhiteSpace", true).
    option("IgnoreTrailingWhiteSpace", true).
    csv(path)

2.Then using to_timestamp function change type to string to timestamp:

from spark >= 2.2

df.withColumn("<MM/dd/yyyy_field_name>",to_timestamp(col("<MM/dd/yyyy_field_name>","MM/dd/yyyy HH:mm:ss"))

3.Using from_unixtime and unix_timestamp functions:

df.withColumn("<MM/dd/yyyy_field_name>",from_unixtime(unix_timestamp(col("<MM/dd/yyyy_field_name>"),"dd/MM/yyyy HH:mm:ss"),"yyyy-MM-dd HH:mm:ss").cast("timestamp"))

4.Using unix_timestamp and casting to timestamp type:

df.withColumn("<MM/dd/yyyy_field_name>",unix_timestamp(col("<MM/dd/yyyy_field_name>"),"dd/MM/yyyy HH:mm:ss").cast("timestamp"))

More dynamic way:

#input dataframe
df.show()
+-------------------+-------------------+-------------------+
|                 dt|                st1|                dt1|
+-------------------+-------------------+-------------------+
|12/12/2019 09:23:23|12/12/2019 09:23:23|12/12/2019 09:23:23|
|12/13/2018 12:23:23|12/13/2018 12:23:23|12/13/2018 12:23:23|
+-------------------+-------------------+-------------------+
#filter all matching rows starts with dt and cast to timestamp

val df2= df.columns.filter(_.startsWith("dt")).foldLeft(df)((df, c) => {
  df.withColumn(s"$c",unix_timestamp(col(s"$c"),"dd/MM/yyyy HH:mm:ss").cast("timestamp"))
})

df2.show(false)

#dynamically changed the format and casted to timestamp for dt,dt1 columns.
//+---------------------+-------------------+---------------------+
//|dt                   |st1                |dt1                  |
//+---------------------+-------------------+---------------------+
//|2019-12-12 09:23:23.0|12/12/2019 09:23:23|2019-12-12 09:23:23.0|
//|2019-01-12 12:23:23.0|12/13/2018 12:23:23|2019-01-12 12:23:23.0|
//+---------------------+-------------------+---------------------+


问:
Params disappearing when using Tempus dominus bootstrap4
I'm trying to use the Tempus Dominus Datetime picker in my app.  Everything seems to work fine, but when I try to convert the submitted string into a datetime object in my controller, I get a TypeError (no implicit conversion of nil into String).  I've also tried to puts the parameters into the logs, but get a blank line.  The odd thing is, during the submission of the form, the parameters do seem to be present.

Processing by EventsController#create as HTML
   Parameters: {"utf8"=>"✓", >"authenticity_token"=>"yuP08tdkavDAzcbJImZXeL0EZ1dp6D13dnLyW/lU+frPVej0tiUmavI>0GKvs66z7+ca2GynI1WWs2d5aSJX5zA==", "event"=>{"title"=>"aaaaa", >"game"=>"bbbb", "start_time"=>"02/21/2020 1:26 PM", "end_time"=>"02/28/2020 >10:46 PM", "description"=>"sasasa"}, "button"=>""}

Here's all relevant code.

Controller:

```<code>class EventsController < ApplicationController
  def new
    @event = Event.new
  end

  def create
    @user = current_user
    if @user
      @user.events.create(title: params[:title], game: params[:game],
                          start_time: time_parse(params[:start_time]),
                          end_time: time_parse(params[:start_time]),
                          description: params[:description])
    end
  end

  private
  def event_params
    params.require(:event).permit(:title, :game, :start_time,:end_time, :description)
  end

  def time_parse(time)
    DateTime.strptime(time, '%m/%d/%Y %M:%S %p')
  end
end

</code>```

View:

```<code> <div class="col-lg-6">
            <%= form_for @event, url: events_path do |form| %>
              <div class="form-row">
                <div class="col-md-6 form-group">
                  <%= form.text_field :title, class: "form-control", placeholder: "Party Title" %>
                </div>

                <div class="col-md-6 form-group">
                  <%= form.text_field :game, class: "form-control", placeholder: "Game" %>
                </div>
              </div>

              <div class="row">
                <div class='col-md-6'>
                  <div class='form-group'>
                    <%= form.label :start_time, 'Start Date and Time', class: 'control-label' %><br>
                    <div class="input-group date" id="datetimepicker1" data-target-input="nearest">
                      <%= form.text_field(:start_time,
                        value: form.object.start_time ? form.object.start_time.strftime('%B %d, %Y %I:%M %p') : nil,
                        class: "form-control datetimepicker-input", data: {target:"#datetimepicker1"}) %>
                      <div class="input-group-append" data-target="#datetimepicker1" data-toggle="datetimepicker">
                        <div class="input-group-text"><i class="fas fa-calendar-plus"></i></div>
                      </div>
                    </div>
                  </div>
                </div>
                <div class='col-md-6'>
                  <div class='form-group'>
                    <%= form.label :end_time, 'End Date and Time', class: 'control-label' %><br>
                    <div class="input-group date" id="datetimepicker2" data-target-input="nearest">
                      <%= form.text_field(:end_time,
                        value: form.object.end_time ? form.object.end_time.strftime('%B %d, %Y %I:%M %p') : nil,
                        class: "form-control datetimepicker-input", data: {target:"#datetimepicker2"}) %>
                      <div class="input-group-append" data-target="#datetimepicker2" data-toggle="datetimepicker">
                        <div class="input-group-text"><i class="fas fa-calendar-plus"></i></div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <div class="col-md-6 form-group">
              </div>
                <%= form.text_area :description, class: "form-control", size: "24x6", placeholder: "Describe your meetup"%>
              </div>

              <div class="text-center "><%= form.button "Sign up", class: "sub-but" %></div>
            <% end %>

          </div>
</code>```

Javascript for view:

```<code>$('#datetimepicker1').datetimepicker({
  format: 'MMMM D, YYYY h:mm A',
  stepping: 15,
  minDate: Date(),
  maxDate: new Date(Date.now() + (365 * 24 * 60 * 60 * 1000)),
  sideBySide: true,
  icons: {
    up: 'fas fa-arrow-up',
    down: 'fas fa-arrow-down',
    previous: 'fas fa-chevron-left',
    next: 'fas fa-chevron-right',
    close: 'fas fa-times'
  },
  buttons: {showClose: true }
});

$('#datetimepicker2').datetimepicker({
  format: 'MMMM D, YYYY h:mm A',
  stepping: 15,
  useCurrent: false,
  sideBySide: true,
  icons: {
    up: 'fas fa-arrow-up',
    down: 'fas fa-arrow-down',
    previous: 'fas fa-chevron-left',
    next: 'fas fa-chevron-right',
    close: 'fas fa-times'
  },
  buttons: {showClose: true }
});
$("#datetimepicker1").on("change.datetimepicker", function (e) {
  $('#datetimepicker2').datetimepicker('minDate', e.date);
  console.log(e.date);
});
$("#datetimepicker2").on("change.datetimepicker", function (e) {
  $('#datetimepicker1').datetimepicker('maxDate', e.date);
});
</code>```

答:
I think you are not linking to the params correctly, also I noticed you have the :start_time going into both in your code above, I assume that is a typo so I changed it in my answer. If it isn't a typo then keep that as is.

```<code>...
start_time: time_parse(params[:event][:start_time]),
end_time: time_parse(params[:event][:end_time]),
...
</code>```

Body:
I'm trying to use the Tempus Dominus Datetime picker in my app.  Everything seems to work fine, but when I try to convert the submitted string into a datetime object in my controller, I get a TypeError (no implicit conversion of nil into String).  I've also tried to puts the parameters into the logs, but get a blank line.  The odd thing is, during the submission of the form, the parameters do seem to be present.

Processing by EventsController#create as HTML
   Parameters: {"utf8"=>"✓", >"authenticity_token"=>"yuP08tdkavDAzcbJImZXeL0EZ1dp6D13dnLyW/lU+frPVej0tiUmavI>0GKvs66z7+ca2GynI1WWs2d5aSJX5zA==", "event"=>{"title"=>"aaaaa", >"game"=>"bbbb", "start_time"=>"02/21/2020 1:26 PM", "end_time"=>"02/28/2020 >10:46 PM", "description"=>"sasasa"}, "button"=>""}

Here's all relevant code.

Controller:

class EventsController < ApplicationController
  def new
    @event = Event.new
  end

  def create
    @user = current_user
    if @user
      @user.events.create(title: params[:title], game: params[:game],
                          start_time: time_parse(params[:start_time]),
                          end_time: time_parse(params[:start_time]),
                          description: params[:description])
    end
  end

  private
  def event_params
    params.require(:event).permit(:title, :game, :start_time,:end_time, :description)
  end

  def time_parse(time)
    DateTime.strptime(time, '%m/%d/%Y %M:%S %p')
  end
end

View:

            <%= form_for @event, url: events_path do |form| %>

                  <%= form.text_field :title, class: "form-control", placeholder: "Party Title" %>

                  <%= form.text_field :game, class: "form-control", placeholder: "Game" %>

                    <%= form.label :start_time, 'Start Date and Time', class: 'control-label' %>

                      <%= form.text_field(:start_time,
                        value: form.object.start_time ? form.object.start_time.strftime('%B %d, %Y %I:%M %p') : nil,
                        class: "form-control datetimepicker-input", data: {target:"#datetimepicker1"}) %>

                    <%= form.label :end_time, 'End Date and Time', class: 'control-label' %>

                      <%= form.text_field(:end_time,
                        value: form.object.end_time ? form.object.end_time.strftime('%B %d, %Y %I:%M %p') : nil,
                        class: "form-control datetimepicker-input", data: {target:"#datetimepicker2"}) %>

                <%= form.text_area :description, class: "form-control", size: "24x6", placeholder: "Describe your meetup"%>

<%= form.button "Sign up", class: "sub-but" %>

            <% end %>

Javascript for view:

$('#datetimepicker1').datetimepicker({
  format: 'MMMM D, YYYY h:mm A',
  stepping: 15,
  minDate: Date(),
  maxDate: new Date(Date.now() + (365 * 24 * 60 * 60 * 1000)),
  sideBySide: true,
  icons: {
    up: 'fas fa-arrow-up',
    down: 'fas fa-arrow-down',
    previous: 'fas fa-chevron-left',
    next: 'fas fa-chevron-right',
    close: 'fas fa-times'
  },
  buttons: {showClose: true }
});

$('#datetimepicker2').datetimepicker({
  format: 'MMMM D, YYYY h:mm A',
  stepping: 15,
  useCurrent: false,
  sideBySide: true,
  icons: {
    up: 'fas fa-arrow-up',
    down: 'fas fa-arrow-down',
    previous: 'fas fa-chevron-left',
    next: 'fas fa-chevron-right',
    close: 'fas fa-times'
  },
  buttons: {showClose: true }
});
$("#datetimepicker1").on("change.datetimepicker", function (e) {
  $('#datetimepicker2').datetimepicker('minDate', e.date);
  console.log(e.date);
});
$("#datetimepicker2").on("change.datetimepicker", function (e) {
  $('#datetimepicker1').datetimepicker('maxDate', e.date);
});

Body:
I think you are not linking to the params correctly, also I noticed you have the :start_time going into both in your code above, I assume that is a typo so I changed it in my answer. If it isn't a typo then keep that as is.

...
start_time: time_parse(params[:event][:start_time]),
end_time: time_parse(params[:event][:end_time]),
...


问:
RPG 4: Cast signed integer to Date and Time
I need cast timestamp (in Signed Int) to Date and Time.
How can I do it?

Idea:

```<code>D  stampint                     10I 0     //- value: '1455554435' - input parm
D  Varprint                     10A
D  Varprint2                     8A 0

 /free
   Varprint  = %char(%date( (<cast to timestamp> stampint) :*MDY));
   Varprint2 = %char(%time( (<cast to timestamp> stampint) :*HMS));
   dsply Varprint;
   dsply Varprint;
   inlr = *on;
   return ;
 /End-free

 Objective result:
   DSPLY 02/15/2016
   DSPLY 16:40:35
</code>```

Thanks.

UPDATE: Sorry, I put the question so fast that I didn't report it correctly.

The objective is to be able to report date and time, regardless of the type of variable. Var1 can be * CHAR or numeric (Packed). Varprint and Varprint2 are a example, but I would like to know how to cast from type I to type Z.

I have tried to use:

```<code>D timestmp          Z inz('1970-01-01-00.00.00.000000')
D result            Z inz('0001-01-01-00.00.00.000000')
... code..
 /free
   result = timestmp + %seconds(stampint);
   dsply result;
 /end-free
</code>```

But result is wrong.

I've tried too:

```<code>Varprint  = %char(%date( %editc(stampint:'Z') :*MDY));
</code>```

But it give compilation error: *RNF7416- The types of the right and left hand side do not ma
the EVAL operation.

答:
You'd need to use %timestamp(), except that an 10 digit integer isn't big enough for a actual timestamp... 6 digits for a date and 6 digits for a time (including seconds)

Best bet would be to use %editc(sampint:'X') to convert to a character string with lead zeros, then %subst() to break out the date and what I assume is only 'HH:MI' for a time...

If you want to convert to an actual time type, you'll need to concat ':00' for seconds in order to use %time();

Body:
I need cast timestamp (in Signed Int) to Date and Time.
How can I do it?

Idea:

D  stampint                     10I 0     //- value: '1455554435' - input parm
D  Varprint                     10A
D  Varprint2                     8A 0

 /free
   Varprint  = %char(%date( (<cast to timestamp> stampint) :*MDY));
   Varprint2 = %char(%time( (<cast to timestamp> stampint) :*HMS));
   dsply Varprint;
   dsply Varprint;
   inlr = *on;
   return ;
 /End-free

 Objective result:
   DSPLY 02/15/2016
   DSPLY 16:40:35

Thanks.

UPDATE: Sorry, I put the question so fast that I didn't report it correctly.

The objective is to be able to report date and time, regardless of the type of variable. Var1 can be * CHAR or numeric (Packed). Varprint and Varprint2 are a example, but I would like to know how to cast from type I to type Z.

I have tried to use:

D timestmp          Z inz('1970-01-01-00.00.00.000000')
D result            Z inz('0001-01-01-00.00.00.000000')
... code..
 /free
   result = timestmp + %seconds(stampint);
   dsply result;
 /end-free

But result is wrong.

I've tried too:

Varprint  = %char(%date( %editc(stampint:'Z') :*MDY));

But it give compilation error: *RNF7416- The types of the right and left hand side do not ma
the EVAL operation.


问:
Manipulating jQuery to get an error: "jQuery requires a window and a document"
If anyone flicked through the uncompressed version of jQuery, one may encounter something like:

```<code>if ( typeof module === "object" && typeof module.exports === "object" ) {

        // For CommonJS and CommonJS-like environments where a proper `window`
        // is present, execute the factory and get jQuery.
        // For environments that do not have a `window` with a `document`
        // (such as Node.js), expose a factory as module.exports.
        // This accentuates the need for the creation of a real `window`.
        // e.g. var jQuery = require("jquery")(window);
        // See ticket #14549 for more info.
        module.exports = global.document ?
            factory( global, true ) :
            function( w ) {
                if ( !w.document ) {
                    throw new Error( "jQuery requires a window with a document" );
                }
                return factory( w );
            };
    } else {
        factory( global );
    }
</code>```

Notice the throw new Error() part. If I am not mistaken, it only throws the error if a window and document are not present. I am aware that things like Node.js could trigger this error, but can a normal HTML, CSS and JS web page trigger this in any way?

答:
Node.js will not throw an error here since it contains a global object with a "document" inside it; you can use jquery with Node.js.

You'd be better off using CherrioJS, which is designed specifically to be "like jQuery but for the server.

Attempts to use jQuery with "ElectronJS" or "Headless Chrome" are examples where this error will throw.

Body:
If anyone flicked through the uncompressed version of jQuery, one may encounter something like:

if ( typeof module === "object" && typeof module.exports === "object" ) {

        // For CommonJS and CommonJS-like environments where a proper `window`
        // is present, execute the factory and get jQuery.
        // For environments that do not have a `window` with a `document`
        // (such as Node.js), expose a factory as module.exports.
        // This accentuates the need for the creation of a real `window`.
        // e.g. var jQuery = require("jquery")(window);
        // See ticket #14549 for more info.
        module.exports = global.document ?
            factory( global, true ) :
            function( w ) {
                if ( !w.document ) {
                    throw new Error( "jQuery requires a window with a document" );
                }
                return factory( w );
            };
    } else {
        factory( global );
    }

Notice the throw new Error() part. If I am not mistaken, it only throws the error if a window and document are not present. I am aware that things like Node.js could trigger this error, but can a normal HTML, CSS and JS web page trigger this in any way?


问:
Reading Bitmap from another activity -> Empty Image
Background:
To give a bit of background ⇒ the app should simply show the user an area (SignatureActivity / SignatureCanvasView) to put a signature. I found a snippet, which works pretty well to draw in.

Issue: Trying to retrieve the bitmap in the MainActivity to show it in an ImageView shows an empty Image. Also writing the retrieved Bitmap creates an png file, which is pretty much empty, since it has even not a background color.

That's how it's done in MainActivity:

```<code>    private void insertSignature(){
        ivSign.setImageBitmap(signature);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        if(requestCode == SIGNATURE_REQUEST){
            if(resultCode == RESULT_OK){
                signature = BitmapFactory.decodeByteArray(data.getByteArrayExtra("SignatureBitmap"), 0, data.getByteArrayExtra("SignatureBitmap").length);
                //signature = (Bitmap) getIntent().getParcelableExtra("SignatureBitmap");
                if(signature != null){
                    insertSignature();
                    Log.e("ActivityResult: ", "SignatureActivity finished with RESULT_OK");
                }
            }else if(resultCode == RESULT_CANCELED){
                Log.e("ActivityResult: ", "SignatureActivity was cancelled");
            }else{
                Log.e("ActivityResult", "Unknown activity result!");
            }
        }

    }
</code>```

That is the code for the view (SignatureCanvasView), which maintains the signature functionality:

```<code>public class SignatureCanvasView extends View {
    public int width;
    public int height;
    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    Context context;
    private Paint mPaint;
    private float mX, mY;
    private static final float TOLERANCE = 5;

    public SignatureCanvasView(Context c, AttributeSet attrs) {
        super(c, attrs);
        context = c;

        // we set a new Path
        mPath = new Path();

        // and we set a new Paint with the desired attributes
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeWidth(2f);
    }

    public byte[] getBitmap() {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        mBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();

        return byteArray;
    }

    // override onSizeChanged
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        // your Canvas will draw onto the defined Bitmap
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
    }

    // override onDraw
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // draw the mPath with the mPaint on the canvas when onDraw
        canvas.drawPath(mPath, mPaint);
    }

    // when ACTION_DOWN start touch according to the x,y values
    private void startTouch(float x, float y) {
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }

    // when ACTION_MOVE move touch according to the x,y values
    private void moveTouch(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOLERANCE || dy >= TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mX = x;
            mY = y;
        }
    }

    public void clearCanvas() {
        mPath.reset();
        invalidate();
    }

    // when ACTION_UP stop touch
    private void upTouch() {
        mPath.lineTo(mX, mY);
    }

    //override the onTouchEvent
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startTouch(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                moveTouch(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                upTouch();
                invalidate();
                break;
        }
        return true;
    }
}
</code>```

The getBitmap()-method of the SignatureCanvasView is called in SignatureActivity to put it as extra, before finishing:

```<code>public class SignatureActivity extends AppCompatActivity {
    //...
    public void Save(){
        this.getIntent().putExtra("SignatureBitmap",scw.getBitmap());
        setResult(RESULT_OK,this.getIntent());
        finish();
    }
    //...
}
</code>```

I appreaciate any hints and suggestions to solve the issue.

答:
You are drawing Path onto canvas attached with SignatureCanvasView, not on the canvas attached with Bitmap mBitmap.

```<code>// override onDraw
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // draw the mPath with the mPaint on the canvas when onDraw
    // canvas.drawPath(mPath, mPaint);
    boolean drawPathTwice = true;
    if (drawPathTwice) {
        canvas.drawPath(mPath, mPaint); // this will be visible to user
        mCanvas.drawPath(mPath, mPaint);// draw path onto canvas attached with mBitmap
        // drawing path 2 times(wasting resources).
    } else {
        mCanvas.drawPath(mPath, mPaint);  // draw path onto canvas attached with mBitmap
        canvas.drawBitmap(mBitmap, 0, 0, null);
        // we have drawn path onto bitmap canvas, so view's canvas will be
        // empty, to give touch feedback we can draw our bitmap containing
        // path onto view's canvas.
    }
}
</code>```

Better option would be to have a class scope boolean which will control
     drawing on bitmap (you can set it to true in upTouch() method).

```<code>@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawPath(mPath, mPaint);

    if (drawOnBitmap) {  // this code will be executed only on ACTION_UP
        // event
        mCanvas.drawPath(mPath, mPaint);  // draw path onto canvas attached with mBitmap
        drawOnBitmap = false;
    }
}
</code>```

Body:
Background:
To give a bit of background ⇒ the app should simply show the user an area (SignatureActivity / SignatureCanvasView) to put a signature. I found a snippet, which works pretty well to draw in.

Issue: Trying to retrieve the bitmap in the MainActivity to show it in an ImageView shows an empty Image. Also writing the retrieved Bitmap creates an png file, which is pretty much empty, since it has even not a background color.

That's how it's done in MainActivity:

    private void insertSignature(){
        ivSign.setImageBitmap(signature);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        if(requestCode == SIGNATURE_REQUEST){
            if(resultCode == RESULT_OK){
                signature = BitmapFactory.decodeByteArray(data.getByteArrayExtra("SignatureBitmap"), 0, data.getByteArrayExtra("SignatureBitmap").length);
                //signature = (Bitmap) getIntent().getParcelableExtra("SignatureBitmap");
                if(signature != null){
                    insertSignature();
                    Log.e("ActivityResult: ", "SignatureActivity finished with RESULT_OK");
                }
            }else if(resultCode == RESULT_CANCELED){
                Log.e("ActivityResult: ", "SignatureActivity was cancelled");
            }else{
                Log.e("ActivityResult", "Unknown activity result!");
            }
        }

    }

That is the code for the view (SignatureCanvasView), which maintains the signature functionality:

public class SignatureCanvasView extends View {
    public int width;
    public int height;
    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    Context context;
    private Paint mPaint;
    private float mX, mY;
    private static final float TOLERANCE = 5;

    public SignatureCanvasView(Context c, AttributeSet attrs) {
        super(c, attrs);
        context = c;

        // we set a new Path
        mPath = new Path();

        // and we set a new Paint with the desired attributes
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeWidth(2f);
    }

    public byte[] getBitmap() {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        mBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();

        return byteArray;
    }

    // override onSizeChanged
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        // your Canvas will draw onto the defined Bitmap
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
    }

    // override onDraw
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // draw the mPath with the mPaint on the canvas when onDraw
        canvas.drawPath(mPath, mPaint);
    }

    // when ACTION_DOWN start touch according to the x,y values
    private void startTouch(float x, float y) {
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }

    // when ACTION_MOVE move touch according to the x,y values
    private void moveTouch(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOLERANCE || dy >= TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mX = x;
            mY = y;
        }
    }

    public void clearCanvas() {
        mPath.reset();
        invalidate();
    }

    // when ACTION_UP stop touch
    private void upTouch() {
        mPath.lineTo(mX, mY);
    }

    //override the onTouchEvent
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startTouch(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                moveTouch(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                upTouch();
                invalidate();
                break;
        }
        return true;
    }
}

The getBitmap()-method of the SignatureCanvasView is called in SignatureActivity to put it as extra, before finishing:

public class SignatureActivity extends AppCompatActivity {
    //...
    public void Save(){
        this.getIntent().putExtra("SignatureBitmap",scw.getBitmap());
        setResult(RESULT_OK,this.getIntent());
        finish();
    }
    //...
}

I appreaciate any hints and suggestions to solve the issue.

Body:
You are drawing Path onto canvas attached with SignatureCanvasView, not on the canvas attached with Bitmap mBitmap.

// override onDraw
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // draw the mPath with the mPaint on the canvas when onDraw
    // canvas.drawPath(mPath, mPaint);
    boolean drawPathTwice = true;
    if (drawPathTwice) {
        canvas.drawPath(mPath, mPaint); // this will be visible to user
        mCanvas.drawPath(mPath, mPaint);// draw path onto canvas attached with mBitmap
        // drawing path 2 times(wasting resources).
    } else {
        mCanvas.drawPath(mPath, mPaint);  // draw path onto canvas attached with mBitmap
        canvas.drawBitmap(mBitmap, 0, 0, null);
        // we have drawn path onto bitmap canvas, so view's canvas will be
        // empty, to give touch feedback we can draw our bitmap containing
        // path onto view's canvas.
    }
}

Better option would be to have a class scope boolean which will control
     drawing on bitmap (you can set it to true in upTouch() method).

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawPath(mPath, mPaint);

    if (drawOnBitmap) {  // this code will be executed only on ACTION_UP
        // event
        mCanvas.drawPath(mPath, mPaint);  // draw path onto canvas attached with mBitmap
        drawOnBitmap = false;
    }
}


问:
JavaScript Sequencer MIDI file timing resolution (PPQN)
I read a lot about MIDI resolution and studied some codes like Tone.js and heartbeat. But I don't understand why there are different Pulses Per Quarter Note (PPQN) values and what the effect it has on playing notes. When I have 960 PPQN so this means 1 quarter note has 960 ticks, 1 eight note 480 ticks, ect. And if I understand it correctly, the delta time is just a relative value.

What I don't understand right is, what should the PPQN when I play notes in JavScript, and when I set the PPQN why it should have this value? For example I use the WebAudio API for playing notes:

```<code>function nextNote() {
  var quarterBeat = 60.0/tempo;
  nextNoteDuration = nextNoteDuration + (quarterBeat/32);
  currentNote++;
}
</code>```

This way I can play different notes durations. Now when I read the MIDI file, should I just compare the delta time and convert it to my sequencers current playback? For example when I read a MIDI file with this values:

```<code>Tempo = 120
PQN = 960
4 Quarter Notes
</code>```

I read the MIDI file, save the notes in an array (assume the delta time is for each note a 1/4)

```<code>duration = [quarterNote, quarterNote, quarterNote, quarterNote]
</code>```

And play the notes:

```<code>while (nextNoteDuration < audioContext.currentTime) {
  if (duration[i] %32 == 0) playNote(currentNote, nextNoteDuration);
  nextNote();
  i++;
}
</code>```

Should I use PPQN only when exporting a MIDI file? If so, in relation to what should I set the PPQN? I hope someone can explain this to me in more detail.

答:
In a standard MIDI file, there’s information in the file header about “ticks per quarter note”, a.k.a. “parts per quarter” (or “PPQ”). For the purpose of this discussion, we’ll consider “beat” and “quarter note” to be synonymous, so you can think of a “tick” as a fraction of a beat. The PPQ is stated in the last word of information (the last two bytes) of the header chunk that appears at the beginning of the file. The PPQ could be a low number such as 24 or 96, which is often sufficient resolution for simple music, or it could be a larger number such as 480 for higher resolution, or even something like 500 or 1000 if one prefers to refer to time in milliseconds.

What the PPQ means in terms of absolute time depends on the designated tempo. By default, the time signature is 4/4 and the tempo is 120 beats per minute. That can be changed, however, by a “meta event” that specifies a different tempo. (You can read about the Set Tempo meta event message in the file format description document.) The tempo is expressed as a 24-bit number that designates microseconds per quarter-note. That’s kind of upside-down from the way we normally express tempo, but it has some advantages. So, for example, a tempo of 100 bpm would be 600000 microseconds per quarter note, so the MIDI meta event for expressing that would be FF 51 03 09 27 C0 (the last three bytes are the Hex for 600000). The meta event would be preceded by a delta time, just like any other MIDI message in the file, so a change of tempo can occur anywhere in the music.

Delta times are always expressed as a variable-length quantity, the format of which is explained in the document. For example, if the PPQ is 480 (standard in most MIDI sequencing software), a delta time of a dotted quarter note (720 ticks) would be expressed by the two bytes 85 50 (hexadecimal).

So, bearing all that in mind, there is a correspondence between delta times expressed in terms of ticks and note values as we think of them in human terms. The relationship depends on the PPQ specified in the header chunk. For example, if the PPQ is 96 (hex 60), then a note middle C on MIDI channel 10 with a velocity of 127 lasting a dotted quarter note (1.5 beats) would be expressed as
00 99 3C 7F // delta time 0 ticks, 153 60 127
90 99 3C 00 // delta time 144 ticks, 153 60 0

Body:
I read a lot about MIDI resolution and studied some codes like Tone.js and heartbeat. But I don't understand why there are different Pulses Per Quarter Note (PPQN) values and what the effect it has on playing notes. When I have 960 PPQN so this means 1 quarter note has 960 ticks, 1 eight note 480 ticks, ect. And if I understand it correctly, the delta time is just a relative value.

What I don't understand right is, what should the PPQN when I play notes in JavScript, and when I set the PPQN why it should have this value? For example I use the WebAudio API for playing notes:

function nextNote() {
  var quarterBeat = 60.0/tempo;
  nextNoteDuration = nextNoteDuration + (quarterBeat/32);
  currentNote++;
}

This way I can play different notes durations. Now when I read the MIDI file, should I just compare the delta time and convert it to my sequencers current playback? For example when I read a MIDI file with this values:

Tempo = 120
PQN = 960
4 Quarter Notes

I read the MIDI file, save the notes in an array (assume the delta time is for each note a 1/4)

duration = [quarterNote, quarterNote, quarterNote, quarterNote]

And play the notes:

while (nextNoteDuration < audioContext.currentTime) {
  if (duration[i] %32 == 0) playNote(currentNote, nextNoteDuration);
  nextNote();
  i++;
}

Should I use PPQN only when exporting a MIDI file? If so, in relation to what should I set the PPQN? I hope someone can explain this to me in more detail.


问:
I want to convert multiple text file (delimited) to separate Excel using Python in a loop
I have a folder in which there are 128 .txt files and all of them have delimited data that is to be converted into separate Excel files.

I have the code to convert one text file to excel file but I want that all the files should be converted to excel file automatically and saved with the same name.

I am using the following code:

```<code>import xlwt
import xlrd
f = open('Events.txt', 'r+')
row_list = []
for row in f:
   row_list.append(row.split('|'))
column_list = zip(*row_list)
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('Sheet1')
i = 0
for column in column_list:
    for item in range(len(column)):
        worksheet.write(item, i, column[item])
    workbook.save('Excel.xls')
    i+=1
</code>```

All the files are stored in the same folder. I am unable to make a loop in which it will open the text file one by one and convert it to excel and save it with the same name as that of text file and then select second text file and so on for 128 files.

Please help!

Thank you in advance

答:
Try something like this. os.listdir returns all the filenames in your specified directory. Then if it ends in .txt it performs your original code.</p>

```<code>import xlwt
import xlrd
import os

filepath = "C:\\Users\\Documents\\"
for txtfile in os.listdir(filepath):
    if txtfile.endswith('.txt'):
        f = open(filepath + txtfile, 'r+')
        row_list = []
        for row in f:
           row_list.append(row.split('|'))
        column_list = zip(*row_list)
        workbook = xlwt.Workbook()
        worksheet = workbook.add_sheet('Sheet1')
        i = 0
        for column in column_list:
            for item in range(len(column)):
                worksheet.write(item, i, column[item])
            workbook.save(filepath + txtfile + '.xls')
            i+=1
</code>```

Body:
I have a folder in which there are 128 .txt files and all of them have delimited data that is to be converted into separate Excel files.

I have the code to convert one text file to excel file but I want that all the files should be converted to excel file automatically and saved with the same name.

I am using the following code:

import xlwt
import xlrd
f = open('Events.txt', 'r+')
row_list = []
for row in f:
   row_list.append(row.split('|'))
column_list = zip(*row_list)
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('Sheet1')
i = 0
for column in column_list:
    for item in range(len(column)):
        worksheet.write(item, i, column[item])
    workbook.save('Excel.xls')
    i+=1

All the files are stored in the same folder. I am unable to make a loop in which it will open the text file one by one and convert it to excel and save it with the same name as that of text file and then select second text file and so on for 128 files.

Please help!

Thank you in advance

Body:
Try something like this. os.listdir returns all the filenames in your specified directory. Then if it ends in .txt it performs your original code.

import xlwt
import xlrd
import os

filepath = "C:\\Users\\Documents\\"
for txtfile in os.listdir(filepath):
    if txtfile.endswith('.txt'):
        f = open(filepath + txtfile, 'r+')
        row_list = []
        for row in f:
           row_list.append(row.split('|'))
        column_list = zip(*row_list)
        workbook = xlwt.Workbook()
        worksheet = workbook.add_sheet('Sheet1')
        i = 0
        for column in column_list:
            for item in range(len(column)):
                worksheet.write(item, i, column[item])
            workbook.save(filepath + txtfile + '.xls')
            i+=1


问:
Laravel ,in bladeview count with groupBy
I have this in my blade

```<code>{{$apartment -> messages() -> count()}}
</code>```

This gives me back the total of messages relating to an apartment. However, I would like the count to be differentiated according to the "created_at", for example with groupBy and then return the total for each date. Is it possible to do this?

答:
not tested, but it should be work:

```<code>$aGroupedMessages = $apartment->messages()->groupBy(function($date) {
    return Carbon::parse($date->created_at)->format('Y-m-d');
})

foreach ($aGroupedMessages as $sDate => $aMessages) {
    echo $sDate . " => " . count($aMessages);
}
</code>```

$apartment->messages() are collections.
look at https://laravel.com/docs/5.6/collections#method-groupby

Body:
I have this in my blade

{{$apartment -> messages() -> count()}}

This gives me back the total of messages relating to an apartment. However, I would like the count to be differentiated according to the "created_at", for example with groupBy and then return the total for each date. Is it possible to do this?

Body:
not tested, but it should be work:

$aGroupedMessages = $apartment->messages()->groupBy(function($date) {
    return Carbon::parse($date->created_at)->format('Y-m-d');
})

foreach ($aGroupedMessages as $sDate => $aMessages) {
    echo $sDate . " => " . count($aMessages);
}

$apartment->messages() are collections.
look at https://laravel.com/docs/5.6/collections#method-groupby


问:
How to copy text generated by JavaScript?
I have a jsfiddle code to record the time and location of a click on an image. It works fine on any desktop platforms but scrolling and highlighting chunks of the text don’t work on iPad in chrome or safari. So as a workaround, I'd like to be able to copy the list of clicks and times that the javascript generates but not sure how. Any thoughts would be much appreciated.

https://jsfiddle.net/369z8Lxu

```<code><!-- Image Map Generated by http://www.image-map.net/ -->
<img src="https://hecoira.leeds.ac.uk/wp-content/uploads/sites/164/2019/08/0D174AF3-1221-42A4-878E-305FD6D829BF-e1564773811882.jpeg" usemap="#image-map">

<map name="image-map">
    <area target="" alt="IVStand" title="IVStand" href="javascript:ClickOnImageMap('IVStand');" coords="147,258,186,208" shape="rect">
    <area target="" alt="Chair" title="Chair" href="javascript:ClickOnImageMap('chair');" coords="68,262,163,343" shape="rect">
    <area target="" alt="DoorHandle" title="DoorHandle" href="javascript:ClickOnImageMap('DoorHandle');" coords="17,237,62,371" shape="rect">
    <area target="" alt="Bed" title="Bed" href="javascript:ClickOnImageMap('Bed');" coords="176,154,327,224" shape="rect">
    <area target="" alt="Window" title="Window" href="javascript:ClickOnImageMap('Window');" coords="159,119,43,8" shape="rect">
    <area target="" alt="Trolley" title="Trolley" href="javascript:ClickOnImageMap('Trolley');" coords="53,129,138,162" shape="rect">
    <area target="" alt="Sink" title="Sink" href="javascript:ClickOnImageMap('Sink');" coords="503,328,410,284" shape="rect">
    <area target="" alt="ClinicalWaste" title="ClinicalWaste" href="javascript:ClickOnImageMap('ClinicalWaste');" coords="297,327,406,374" shape="rect">
    <area target="" alt="AlcoholGel" title="AlcoholGel" href="javascript:ClickOnImageMap('AlcoholGel');" coords="399,258,504,158,504,241" shape="rect">
</map>

<p id="clicks">
Clicks:<br>
</p>
</code>```

Jscript

```<code>ClickOnImageMap = function(area){
    var oldHtml = document.getElementById("clicks").innerHTML;
  var now  = new Date();
  document.getElementById("clicks").innerHTML = oldHtml + area + ' ' + now.toLocaleString() + '<br>';
}
</code>```

答:
This is a suggestion more than a solution to your 'copy-and-paste' request.
As your difficulty occurs on iPads/ smaller screens, it occurred to me that maybe the layout [of the output] could stand to be adjusted.
For instance, repetitively outputting the name of an area on a new line on every click is bulky, so I would suggest grouping the clicks and simply appending the time/date to the end of that area's list of dates when it is clicked again.
You could add a counter before the list of times to display a count of the number of times an area has been clicked.

Bearing in mind that the list could get long, I would suggest setting a height on paragraphs and setting the overflow to scroll/auto so that if you really want to read a list of times, you can tap down. Or you could elect to show/hide dates if you wish.

I put together a fiddle* (layout modifiable as you wish of course) to give an idea. Please note I didn't have an iPad to test it out; I used logic and my imagination!

Hope this helps

ClickOnImageMap = function(area) {
  var oldHtml = document.getElementById("clicks").innerHTML;
  var newHTML, areaclicks;
  var now = new Date();
  const area1 = 1;
  var spanid = "";

  if (oldHtml.indexOf(area) == -1) {
    var para = document.createElement("P");
    para.setAttribute("id", "" + area + "");
    var cont = document.createTextNode("");
    para.appendChild(cont);
    spanid = area + 1;
    para.innerHTML = area + " Clicks: " + '' + area1 + '' + " " + now.toLocaleString();
    //const info = document.getElementById("clicks");
    document.getElementById("clicks").appendChild(para);
  } else {

    var addto = document.getElementById(area);
    newHTML = addto.innerHTML + " " + now.toLocaleString();
    var areaclicks = ((addto.innerText.match(/,/g) || []).length) + 1;
    console.log("Clicks is " + areaclicks);
    spanid = area + 1;
    addto.innerHTML = newHTML;
    document.getElementById(spanid).innerHTML = areaclicks;

  }

}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#clicks p {
  width: 100%;
  max-height: 35px;
  overflow: auto;
}</code>```

  <map name="image-map">
    <area target="" alt="IVStand" title="IVStand" href="javascript:ClickOnImageMap('IVStand');" coords="147,258,186,208" shape="rect">
    <area target="" alt="Chair" title="Chair" href="javascript:ClickOnImageMap('Chair');" coords="68,262,163,343" shape="rect">
    <area target="" alt="DoorHandle" title="DoorHandle" href="javascript:ClickOnImageMap('DoorHandle');" coords="17,237,62,371" shape="rect">
    <area target="" alt="Bed" title="Bed" href="javascript:ClickOnImageMap('Bed');" coords="176,154,327,224" shape="rect">
    <area target="" alt="Window" title="Window" href="javascript:ClickOnImageMap('Window');" coords="159,119,43,8" shape="rect">
    <area target="" alt="Trolley" title="Trolley" href="javascript:ClickOnImageMap('Trolley');" coords="53,129,138,162" shape="rect">
    <area target="" alt="Sink" title="Sink" href="javascript:ClickOnImageMap('Sink');" coords="503,328,410,284" shape="rect">
    <area target="" alt="ClinicalWaste" title="ClinicalWaste" href="javascript:ClickOnImageMap('ClinicalWaste');" coords="297,327,406,374" shape="rect">
    <area target="" alt="AlcoholGel" title="AlcoholGel" href="javascript:ClickOnImageMap('AlcoholGel');" coords="399,258,504,158,504,241" shape="rect">
</map>

    Clicks

```

*(I entered a snippet, just to show the code. Even though it's the same code as in the fiddle (which runs fine), the snippet didn't run [at time of entering], even in full screen.. hmmm. See fiddle.)

Body:
I have a jsfiddle code to record the time and location of a click on an image. It works fine on any desktop platforms but scrolling and highlighting chunks of the text don’t work on iPad in chrome or safari. So as a workaround, I'd like to be able to copy the list of clicks and times that the javascript generates but not sure how. Any thoughts would be much appreciated.

https://jsfiddle.net/369z8Lxu

<map name="image-map">
    <area target="" alt="IVStand" title="IVStand" href="javascript:ClickOnImageMap('IVStand');" coords="147,258,186,208" shape="rect">
    <area target="" alt="Chair" title="Chair" href="javascript:ClickOnImageMap('chair');" coords="68,262,163,343" shape="rect">
    <area target="" alt="DoorHandle" title="DoorHandle" href="javascript:ClickOnImageMap('DoorHandle');" coords="17,237,62,371" shape="rect">
    <area target="" alt="Bed" title="Bed" href="javascript:ClickOnImageMap('Bed');" coords="176,154,327,224" shape="rect">
    <area target="" alt="Window" title="Window" href="javascript:ClickOnImageMap('Window');" coords="159,119,43,8" shape="rect">
    <area target="" alt="Trolley" title="Trolley" href="javascript:ClickOnImageMap('Trolley');" coords="53,129,138,162" shape="rect">
    <area target="" alt="Sink" title="Sink" href="javascript:ClickOnImageMap('Sink');" coords="503,328,410,284" shape="rect">
    <area target="" alt="ClinicalWaste" title="ClinicalWaste" href="javascript:ClickOnImageMap('ClinicalWaste');" coords="297,327,406,374" shape="rect">
    <area target="" alt="AlcoholGel" title="AlcoholGel" href="javascript:ClickOnImageMap('AlcoholGel');" coords="399,258,504,158,504,241" shape="rect">
</map>

Clicks:

Jscript

ClickOnImageMap = function(area){
    var oldHtml = document.getElementById("clicks").innerHTML;
  var now  = new Date();
  document.getElementById("clicks").innerHTML = oldHtml + area + ' ' + now.toLocaleString() + '
';
}

Body:
This is a suggestion more than a solution to your 'copy-and-paste' request.
As your difficulty occurs on iPads/ smaller screens, it occurred to me that maybe the layout [of the output] could stand to be adjusted.
For instance, repetitively outputting the name of an area on a new line on every click is bulky, so I would suggest grouping the clicks and simply appending the time/date to the end of that area's list of dates when it is clicked again.
You could add a counter before the list of times to display a count of the number of times an area has been clicked.

Bearing in mind that the list could get long, I would suggest setting a height on paragraphs and setting the overflow to scroll/auto so that if you really want to read a list of times, you can tap down. Or you could elect to show/hide dates if you wish.

I put together a fiddle* (layout modifiable as you wish of course) to give an idea. Please note I didn't have an iPad to test it out; I used logic and my imagination!

Hope this helps

ClickOnImageMap = function(area) {
  var oldHtml = document.getElementById("clicks").innerHTML;
  var newHTML, areaclicks;
  var now = new Date();
  const area1 = 1;
  var spanid = "";

  if (oldHtml.indexOf(area) == -1) {
    var para = document.createElement("P");
    para.setAttribute("id", "" + area + "");
    var cont = document.createTextNode("");
    para.appendChild(cont);
    spanid = area + 1;
    para.innerHTML = area + " Clicks: " + '<span id= "' + spanid + '">' + area1 + '</span>' + " " + now.toLocaleString();
    //const info = document.getElementById("clicks");
    document.getElementById("clicks").appendChild(para);
  } else {

    var addto = document.getElementById(area);
    newHTML = addto.innerHTML + " " + now.toLocaleString();
    var areaclicks = ((addto.innerText.match(/,/g) || []).length) + 1;
    console.log("Clicks is " + areaclicks);
    spanid = area + 1;
    addto.innerHTML = newHTML;
    document.getElementById(spanid).innerHTML = areaclicks;

  }

}

#clicks p {
  width: 100%;
  max-height: 35px;
  overflow: auto;
}

<html>

<body>
  <!-- Image Map Generated by http://www.image-map.net/ -->
  <img src="https://hecoira.leeds.ac.uk/wp-content/uploads/sites/164/2019/08/0D174AF3-1221-42A4-878E-305FD6D829BF-e1564773811882.jpeg" usemap="#image-map">

  <map name="image-map">
    <area target="" alt="IVStand" title="IVStand" href="javascript:ClickOnImageMap('IVStand');" coords="147,258,186,208" shape="rect">
    <area target="" alt="Chair" title="Chair" href="javascript:ClickOnImageMap('Chair');" coords="68,262,163,343" shape="rect">
    <area target="" alt="DoorHandle" title="DoorHandle" href="javascript:ClickOnImageMap('DoorHandle');" coords="17,237,62,371" shape="rect">
    <area target="" alt="Bed" title="Bed" href="javascript:ClickOnImageMap('Bed');" coords="176,154,327,224" shape="rect">
    <area target="" alt="Window" title="Window" href="javascript:ClickOnImageMap('Window');" coords="159,119,43,8" shape="rect">
    <area target="" alt="Trolley" title="Trolley" href="javascript:ClickOnImageMap('Trolley');" coords="53,129,138,162" shape="rect">
    <area target="" alt="Sink" title="Sink" href="javascript:ClickOnImageMap('Sink');" coords="503,328,410,284" shape="rect">
    <area target="" alt="ClinicalWaste" title="ClinicalWaste" href="javascript:ClickOnImageMap('ClinicalWaste');" coords="297,327,406,374" shape="rect">
    <area target="" alt="AlcoholGel" title="AlcoholGel" href="javascript:ClickOnImageMap('AlcoholGel');" coords="399,258,504,158,504,241" shape="rect">
</map>

  <h3>
    Clicks
  </h3>
  <p id="clicks">

  </p>

  <!--<script>
 </script>--->
</body>

</html>

*(I entered a snippet, just to show the code. Even though it's the same code as in the fiddle (which runs fine), the snippet didn't run [at time of entering], even in full screen.. hmmm. See fiddle.)