问:
Python remove subgroups in a groupby object based on condition
I have a time series DataFrame involving multiple groups with a 3-level hierarchy (i.e., 3 id columns), together with a date column and a value column. The code I wrote to group them and an example of the result is shown below:

```<code>grp = df.groupby(['level0','level1','level2','date'])

                                        values
level0  level1  level2      date
A       AA      AA_1        2006-10-31  300
                            2006-11-30  220
                            2006-12-31  415
                            2007-04-30  19
                            2007-05-31  77
                            2007-08-31  463
                AA_2        2006-10-31  6630
                            2006-11-30  1980
                            2006-12-31  3367
                            2007-04-30  199
        AB      AB_1        2006-01-31  693
                            2006-05-31  2694
                            2007-09-30  6681
...     ...     ...         ...         ...
Z       ZZ      ZZ_9        2006-04-30  3680
                            2006-09-30  277
                            2007-03-31  1490
                            2007-09-30  289
                            2007-10-31  387
</code>```

I want to remove those in level2 who do not have any records in the last 6 months. Let's say Group A has the maximum date of 2007-12-31, then I want to remove AA_2 because it doesn't have any record in the last 6 months. The desired output will be like this:

```<code>                                        values
level0  level1  level2      date
A       AA      AA_1        2006-10-31  300
                            2006-11-30  220
                            2006-12-31  415
                            2007-04-30  19
                            2007-05-31  77
                            2007-08-31  463
        AB      AB_1        2006-01-31  693
                            2006-05-31  2694
                            2007-09-30  6681
...     ...     ...         ...         ...
Z       ZZ      ZZ_9        2006-04-30  3680
                            2006-09-30  277
                            2007-03-31  1490
                            2007-09-30  289
                            2007-10-31  387
</code>```

I can extract the date range using the following code:

```<code>from dateutil.relativedelta import relativedelta
import pandas as pd

end_date = df.date.max()
start_date = end_date - relativedelta(months=+6 - 1)
test_period = pd.date_range(start=start_date, end=end_date, freq='1M').to_list()

[Timestamp('2007-07-31 00:00:00', freq='M'),
 Timestamp('2007-08-31 00:00:00', freq='M'),
 Timestamp('2007-09-30 00:00:00', freq='M'),
 Timestamp('2007-10-31 00:00:00', freq='M'),
 Timestamp('2007-11-30 00:00:00', freq='M'),
 Timestamp('2007-12-31 00:00:00', freq='M')]
</code>```

However, as each level0 group has a different maximum date (e.g., some collect info up to 2007-12-31 while some 2007-11-30), the code above finds the maximum date of the whole dataset which isn't correct for some groups.

My question is how I can find the maximum date in each level0 group, and delete those having no record at all in the last 6 months?

Thank you in advance! (Any solution is welcome although a speedy one is most desired!)

答:
First create helper DataFrame by MultiIndex.to_frame with DataFrame.add_suffix for rename columns names and for first level get maximal values, subtract 6 months and compare if at least one value of column is greater in s, last test if per first 3 levels is at least one True in GroupBy.transform with GroupBy.any and filter in boolean indexing:

```<code>print (df)
                                 values
level0 level1 level2 date
A      AA     AA_1   2007-12-31     300 <- date change
                     2006-11-30     220
                     2006-12-31     415
                     2007-04-30      19
                     2007-05-31      77
                     2007-08-31     463
              AA_2   2006-10-31    6630
                     2006-11-30    1980
                     2006-12-31    3367
                     2007-04-30     199
       AB     AB_1   2006-01-31     693
                     2006-05-31    2694
                     2007-09-30    6681
</code>```

```<code>df1 = df.index.to_frame().add_suffix('_')

s = df1['date_'].gt(df1.groupby('level0')['date_']
                      .transform('max')
                      .sub(pd.offsets.DateOffset(months=6)))
print (s)
level0  level1  level2  date
A       AA      AA_1    2007-12-31     True
                        2006-11-30    False
                        2006-12-31    False
                        2007-04-30    False
                        2007-05-31    False
                        2007-08-31     True
                AA_2    2006-10-31    False
                        2006-11-30    False
                        2006-12-31    False
                        2007-04-30    False
        AB      AB_1    2006-01-31    False
                        2006-05-31    False
                        2007-09-30     True
Name: date_, dtype: bool
</code>```

```<code>df = df[s.groupby(['level0','level1','level2']).transform('any')]

print (df)
                                 values
level0 level1 level2 date
A      AA     AA_1   2007-12-31     300
                     2006-11-30     220
                     2006-12-31     415
                     2007-04-30      19
                     2007-05-31      77
                     2007-08-31     463
       AB     AB_1   2006-01-31     693
                     2006-05-31    2694
                     2007-09-30    6681
</code>```

Body:
I have a time series DataFrame involving multiple groups with a 3-level hierarchy (i.e., 3 id columns), together with a date column and a value column. The code I wrote to group them and an example of the result is shown below:

grp = df.groupby(['level0','level1','level2','date'])

                                        values
level0  level1  level2      date
A       AA      AA_1        2006-10-31  300
                            2006-11-30  220
                            2006-12-31  415
                            2007-04-30  19
                            2007-05-31  77
                            2007-08-31  463
                AA_2        2006-10-31  6630
                            2006-11-30  1980
                            2006-12-31  3367
                            2007-04-30  199
        AB      AB_1        2006-01-31  693
                            2006-05-31  2694
                            2007-09-30  6681
...     ...     ...         ...         ...
Z       ZZ      ZZ_9        2006-04-30  3680
                            2006-09-30  277
                            2007-03-31  1490
                            2007-09-30  289
                            2007-10-31  387

I want to remove those in level2 who do not have any records in the last 6 months. Let's say Group A has the maximum date of 2007-12-31, then I want to remove AA_2 because it doesn't have any record in the last 6 months. The desired output will be like this:

                                        values
level0  level1  level2      date
A       AA      AA_1        2006-10-31  300
                            2006-11-30  220
                            2006-12-31  415
                            2007-04-30  19
                            2007-05-31  77
                            2007-08-31  463
        AB      AB_1        2006-01-31  693
                            2006-05-31  2694
                            2007-09-30  6681
...     ...     ...         ...         ...
Z       ZZ      ZZ_9        2006-04-30  3680
                            2006-09-30  277
                            2007-03-31  1490
                            2007-09-30  289
                            2007-10-31  387

I can extract the date range using the following code:

from dateutil.relativedelta import relativedelta
import pandas as pd

end_date = df.date.max()
start_date = end_date - relativedelta(months=+6 - 1)
test_period = pd.date_range(start=start_date, end=end_date, freq='1M').to_list()

[Timestamp('2007-07-31 00:00:00', freq='M'),
 Timestamp('2007-08-31 00:00:00', freq='M'),
 Timestamp('2007-09-30 00:00:00', freq='M'),
 Timestamp('2007-10-31 00:00:00', freq='M'),
 Timestamp('2007-11-30 00:00:00', freq='M'),
 Timestamp('2007-12-31 00:00:00', freq='M')]

However, as each level0 group has a different maximum date (e.g., some collect info up to 2007-12-31 while some 2007-11-30), the code above finds the maximum date of the whole dataset which isn't correct for some groups.

My question is how I can find the maximum date in each level0 group, and delete those having no record at all in the last 6 months?

Thank you in advance! (Any solution is welcome although a speedy one is most desired!)

Body:
First create helper DataFrame by MultiIndex.to_frame with DataFrame.add_suffix for rename columns names and for first level get maximal values, subtract 6 months and compare if at least one value of column is greater in s, last test if per first 3 levels is at least one True in GroupBy.transform with GroupBy.any and filter in boolean indexing:

print (df)
                                 values
level0 level1 level2 date
A      AA     AA_1   2007-12-31     300 <- date change
                     2006-11-30     220
                     2006-12-31     415
                     2007-04-30      19
                     2007-05-31      77
                     2007-08-31     463
              AA_2   2006-10-31    6630
                     2006-11-30    1980
                     2006-12-31    3367
                     2007-04-30     199
       AB     AB_1   2006-01-31     693
                     2006-05-31    2694
                     2007-09-30    6681

df1 = df.index.to_frame().add_suffix('_')

s = df1['date_'].gt(df1.groupby('level0')['date_']
                      .transform('max')
                      .sub(pd.offsets.DateOffset(months=6)))
print (s)
level0  level1  level2  date
A       AA      AA_1    2007-12-31     True
                        2006-11-30    False
                        2006-12-31    False
                        2007-04-30    False
                        2007-05-31    False
                        2007-08-31     True
                AA_2    2006-10-31    False
                        2006-11-30    False
                        2006-12-31    False
                        2007-04-30    False
        AB      AB_1    2006-01-31    False
                        2006-05-31    False
                        2007-09-30     True
Name: date_, dtype: bool

df = df[s.groupby(['level0','level1','level2']).transform('any')]

print (df)
                                 values
level0 level1 level2 date
A      AA     AA_1   2007-12-31     300
                     2006-11-30     220
                     2006-12-31     415
                     2007-04-30      19
                     2007-05-31      77
                     2007-08-31     463
       AB     AB_1   2006-01-31     693
                     2006-05-31    2694
                     2007-09-30    6681


来源: stackexchange

问:
Using loop to write excel files in R
I have a list of data frames that I would like to export to excel. Exporting each data frame would be very tedious and error prone. Is there a way to achieve this using for loop or map functions? The desire would also be export all the data frames into one workbook.</p>
```<code>library(tidyverse)
library(writexl)

df <- tribble(
  ~var1, ~var2, ~group,
  12, 11, "A",
  15, 10, "B",
  16, 18, "A",
  18, 14, "C",
  18, 3, "A",
  10, 17, "B",
  20, 1, "A",
  10, 13, "A"
)

nest(df, data = c(var1, var2))

sheet1 <- df %>% filter(group == "A")
sheet2 <- df %>% filter(group == "B")
sheet3 <- df %>% filter(group == "C")

write_xlsx(sheet1, "sheet1.xlsx")
write_xlsx(sheet2, "sheet2.xlsx")
write_xlsx(sheet3, "sheet3.xlsx")

</code>```

答:
In write_xlsx "to create an xlsx with (multiple) named sheets, simply set x to a named list of data frames." So you can do the following to achieve what you are asking for:

```<code>groups <- distinct(df, group) %>% pull(group)

list_of_dfs <-  groups %>%
  map(~ df %>% filter(group == .x))

names(list_of_dfs) <- groups

write_xlsx(list_of_dfs, "out.xlsx")
</code>```

ContentLicense: CC BY-SA 4.0

Title: Using loop to write excel files in R

Body:
I have a list of data frames that I would like to export to excel. Exporting each data frame would be very tedious and error prone. Is there a way to achieve this using for loop or map functions? The desire would also be export all the data frames into one workbook.

library(tidyverse)
library(writexl)

df <- tribble(
  ~var1, ~var2, ~group,
  12, 11, "A",
  15, 10, "B",
  16, 18, "A",
  18, 14, "C",
  18, 3, "A",
  10, 17, "B",
  20, 1, "A",
  10, 13, "A"
)

nest(df, data = c(var1, var2))

sheet1 <- df %>% filter(group == "A")
sheet2 <- df %>% filter(group == "B")
sheet3 <- df %>% filter(group == "C")

write_xlsx(sheet1, "sheet1.xlsx")
write_xlsx(sheet2, "sheet2.xlsx")
write_xlsx(sheet3, "sheet3.xlsx")

Body:
In write_xlsx "to create an xlsx with (multiple) named sheets, simply set x to a named list of data frames." So you can do the following to achieve what you are asking for:

groups <- distinct(df, group) %>% pull(group)

list_of_dfs <-  groups %>%
  map(~ df %>% filter(group == .x))

names(list_of_dfs) <- groups

write_xlsx(list_of_dfs, "out.xlsx")


问:
How can we get the current selected item from the Dropdown Search Package in Flutter
I am using this package
https://pub.dev/packages/dropdown_search

I have a dropdown inside a form I made, when a user selects an item, I would like to get the value of the selection and assign it to a variable. I've read some docs but they are quite hard to understand in regards to getting the value out. As far as I understood, the SelectedItem property is only to set a starting selection. How can I get the selected item from the dropdown?

 DropdownSearch<String>(
                  mode: Mode.MENU,
                  showSearchBox: false,
                  showSelectedItems: true,
                  items: const [
                    'Item 1',
                    'Item 2',
                    'Item 3',
                  ],
                  dropdownSearchDecoration: InputDecoration(
                    labelText: 'Items',
                  ),
                ),
```

In my above code, I'm not understanding how I should get the selected item, I am uploading the selected item to Firestore.

答:
I added an example for you, please check it

 DropdownSearch<String>(
                  mode: Mode.MENU,
                  showSearchBox: false,
                  showSelectedItems: true,
                  items: const [
                    'Item 1',
                    'Item 2',
                    'Item 3',
                  ],
                  dropdownSearchDecoration: InputDecoration(
                    labelText: 'Items',
                  ),
                  onChanged: (String selectedValue) {
                    yourVariable = selectedValue; // you should change this line according to your own
                  },
                ),
```

Body:
I am using this package
https://pub.dev/packages/dropdown_search

I have a dropdown inside a form I made, when a user selects an item, I would like to get the value of the selection and assign it to a variable. I've read some docs but they are quite hard to understand in regards to getting the value out. As far as I understood, the SelectedItem property is only to set a starting selection. How can I get the selected item from the dropdown?

 DropdownSearch<String>(
                  mode: Mode.MENU,
                  showSearchBox: false,
                  showSelectedItems: true,
                  items: const [
                    'Item 1',
                    'Item 2',
                    'Item 3',
                  ],
                  dropdownSearchDecoration: InputDecoration(
                    labelText: 'Items',
                  ),
                ),

In my above code, I'm not understanding how I should get the selected item, I am uploading the selected item to Firestore.


问:
Issue with image in django
I have problem with image in django. I get 404.

Settings.py

```<code>MEDIA_ROOT = 'static/image/'
MEDIA_URL = 'image/'
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
    ]
</code>```

Models.py

```<code>    img = models.ImageField(upload_to = '', verbose_name= 'Картинка',null=True )
</code>```

(P.S I tried everything,but it isnt working)

答:
Have you got your answer or not if not try this

Add this in your settings.py file

```<code>MEDIA_ROOT = os.path.join(BASE_DIR, 'media') #new
MEDIA_URL = '/media/' #new
</code>```

After Add in your main urls.py file add these config

```<code>from django.conf import settings     #new
from django.conf.urls.static import static  #new
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('App.urls'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)      #media
</code>```

Title: Issue with image in django

Body:
I have problem with image in django. I get 404.

Settings.py

MEDIA_ROOT = 'static/image/'
MEDIA_URL = 'image/'
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
    ]

Models.py

    img = models.ImageField(upload_to = '', verbose_name= 'Картинка',null=True )

(P.S I tried everything,but it isnt working)

Body:
Have you got your answer or not if not try this

Add this in your settings.py file

MEDIA_ROOT = os.path.join(BASE_DIR, 'media') #new
MEDIA_URL = '/media/' #new

After Add in your main urls.py file add these config

from django.conf import settings     #new
from django.conf.urls.static import static  #new
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('App.urls'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)      #media


问:
How to remove default margin in react bootstrap?
I am creating a home page in react using bootstrap but everything is coming automatically using different margins in both sides on the container. How to make the 'section' container so that it will cover both sides in any screen size.
P.S. I have tried putting marginBotton:-10rem but as soon as screen size changes it distorts everything,

```<code>class Home extends Component {

render() {
    return (
      <div>
         <div className="container">
                <Navbar style={{marginBottom: "0"}} inverse className="fixed-top collapseOnSelect nav-bar" bg='dark' expand='sm'>
                <Navbar.Toggle aria-controls="basic-navbar-nav" />
                <Navbar.Collapse id="basic-navbar-nav">
                <a href="/alogin" class="navbar-brand text-white">Tailoring Store</a>
                <Nav className="ms-auto navbar-dark py-3">

        <NavLink className= "d-inline p-2 bg-dark text-white" style={{textDecoration:'none'}} to="/alogin">Login as Admin</NavLink>
                    <NavLink className= "d-inline p-2 bg-dark text-white" style={{textDecoration:'none'}} to="/tlogin">Login as Tailor</NavLink>
                    <NavLink className= "d-inline p-2 bg-dark text-white" style={{textDecoration:'none'}} to="/clogin">Login as Customer</NavLink>
                </Nav>
                </Navbar.Collapse>
            </Navbar>
            </div>
        <div
          className="bg-dark text-light p-5 text-center text-sm-start"
          style={{ marginTop: "4.5rem", marginLeft:"0", padding:"0"  }}
          inverse
        >
          <div className="container">
            <div className="d-sm-flex align-items-center justify-content-between">
              <div>
                <h1>
                  Welcome to the
                  <span className="text-warning">Tailoring Store</span>
                </h1>
                <p className="lead my-5">
                  Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum
                  in dolores impedit ipsam voluptatibus reprehenderit suscipit.
                  Unde quos voluptas explicabo?
                </p>
              </div>
              <img
                className="img-fluid w-30 d-none d-sm-block"
                src="https://seeklogo.com/images/T/tailor-store-logo-22F77490D5-seeklogo.com.png"
              />
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default Home;
</code>```

答:
Simply add fluid, which allows you to available spaces

<Container fluid> ... </Container>

Body:
I am creating a home page in react using bootstrap but everything is coming automatically using different margins in both sides on the container. How to make the 'section' container so that it will cover both sides in any screen size.
P.S. I have tried putting marginBotton:-10rem but as soon as screen size changes it distorts everything,

class Home extends Component {

render() {
    return (

                <Navbar style={{marginBottom: "0"}} inverse className="fixed-top collapseOnSelect nav-bar" bg='dark' expand='sm'>
                <Navbar.Toggle aria-controls="basic-navbar-nav" />
                <Navbar.Collapse id="basic-navbar-nav">
                Tailoring Store

        <NavLink className= "d-inline p-2 bg-dark text-white" style={{textDecoration:'none'}} to="/alogin">Login as Admin</NavLink>
                    <NavLink className= "d-inline p-2 bg-dark text-white" style={{textDecoration:'none'}} to="/tlogin">Login as Tailor</NavLink>
                    <NavLink className= "d-inline p-2 bg-dark text-white" style={{textDecoration:'none'}} to="/clogin">Login as Customer</NavLink>

                </Navbar.Collapse>
            </Navbar>

                  Welcome to the
                  Tailoring Store

                  Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum
                  in dolores impedit ipsam voluptatibus reprehenderit suscipit.
                  Unde quos voluptas explicabo?

    );
  }
}

export default Home;


问:
ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin
SETUP:

Three mysql group replication nodes in master master master.

All work fine. I can add users/dbs and insert/update data.

Each node is bound to a private IP address.

I created a bash script to connect to mysql to delete users.

Deleting a database with a script works fine.

PROBLEM:

The following commands will NOT run. I can create users and databases and delete databases but cant delete the users. I cant tell if its a replication issue OR a privilege issue.

DELETE FROM mysql.user WHERE user='testme123';

DELETE FROM mysql.db   WHERE user='testme123';

DROP USER IF EXISTS 'testme123';

ERROR 3098 (HY000) at line 1: The table does not comply with the requirements by an external plugin.

LOG: [ERROR] Plugin group_replication reported: 'Table user does not use the InnoDB storage engine. This is not compatible with Group Replication.

I get same error via local mysql console too logged in as root.

QUESTION(S):

What could be preventing this?

How can I troubleshoot what it is I am missing?

答:
One of the group replications requirement is -   Every table that is to be replicated by the group must have a defined primary key, or primary key equivalent where the equivalent is a non-null unique key. [link]

So, If you are using a table without fulfilling this condition, server will throw this error. Use a table with Primary ID.


问:
NVM: Getting Permission denied with nvm install command
I recently fresh-installed Ubuntu 21.04 and wanted to install nvm:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash

Then closed and re-opened the terminal. When requesting an install of version 12.16.3 (have tried with other versions as well). I'm getting the following error:

```<code>nvm install 12.16.3
Downloading and installing node v12.16.3...
Downloading https://nodejs.org/dist/v12.16.3/node-v12.16.3-linux-x64.tar.xz...
Warning: Failed to create the file
Warning: /home/sauronnikko/.nvm/.cache/bin/node-v12.16.3-linux-x64/node-v12.16.
Warning: 3-linux-x64.tar.xz: Permission denied
curl: (23) Failure writing output to destination

Binary download from https://nodejs.org/dist/v12.16.3/node-v12.16.3-linux-x64.tar.xz failed, trying source.
grep: /home/sauronnikko/.nvm/.cache/bin/node-v12.16.3-linux-x64/node-v12.16.3-linux-x64.tar.xz: No such file or directory
Provided file to checksum does not exist.
Binary download failed, trying source.
Downloading https://nodejs.org/dist/v12.16.3/node-v12.16.3.tar.xz...
Warning: Failed to create the file
Warning: /home/sauronnikko/.nvm/.cache/src/node-v12.16.3/node-v12.16.3.tar.xz:
Warning: Permission denied
curl: (23) Failure writing output to destination

Binary download from https://nodejs.org/dist/v12.16.3/node-v12.16.3.tar.xz failed, trying source.
grep: /home/sauronnikko/.nvm/.cache/src/node-v12.16.3/node-v12.16.3.tar.xz: No such file or directory
Provided file to checksum does not exist.
</code>```

答:
This worked

In simple words i did this and it worked...

```<code>>snap list
>sudo snap remove curl
</code>```

This will delete curl that was installed through snap.
We need to install using apt

```<code>>sudo apt-get install curl
</code>```

Now we need to install nvm using curl

```<code>>curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
</code>```

Now simply install the node version u want.

```<code>>nvm install v14.17.0
</code>```

In order to list all nvm version simply do so.

```<code>>nvm ls
</code>```

And in order to switch just type the following command.

```<code>>nvm use v12.X.XX
</code>```

Body:
I recently fresh-installed Ubuntu 21.04 and wanted to install nvm:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash

Then closed and re-opened the terminal. When requesting an install of version 12.16.3 (have tried with other versions as well). I'm getting the following error:

nvm install 12.16.3
Downloading and installing node v12.16.3...
Downloading https://nodejs.org/dist/v12.16.3/node-v12.16.3-linux-x64.tar.xz...
Warning: Failed to create the file
Warning: /home/sauronnikko/.nvm/.cache/bin/node-v12.16.3-linux-x64/node-v12.16.
Warning: 3-linux-x64.tar.xz: Permission denied
curl: (23) Failure writing output to destination

Binary download from https://nodejs.org/dist/v12.16.3/node-v12.16.3-linux-x64.tar.xz failed, trying source.
grep: /home/sauronnikko/.nvm/.cache/bin/node-v12.16.3-linux-x64/node-v12.16.3-linux-x64.tar.xz: No such file or directory
Provided file to checksum does not exist.
Binary download failed, trying source.
Downloading https://nodejs.org/dist/v12.16.3/node-v12.16.3.tar.xz...
Warning: Failed to create the file
Warning: /home/sauronnikko/.nvm/.cache/src/node-v12.16.3/node-v12.16.3.tar.xz:
Warning: Permission denied
curl: (23) Failure writing output to destination

Binary download from https://nodejs.org/dist/v12.16.3/node-v12.16.3.tar.xz failed, trying source.
grep: /home/sauronnikko/.nvm/.cache/src/node-v12.16.3/node-v12.16.3.tar.xz: No such file or directory
Provided file to checksum does not exist.

Body:
This worked

In simple words i did this and it worked...

>snap list
>sudo snap remove curl

This will delete curl that was installed through snap.
We need to install using apt

>sudo apt-get install curl

Now we need to install nvm using curl

>curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash

Now simply install the node version u want.

>nvm install v14.17.0

In order to list all nvm version simply do so.

>nvm ls

And in order to switch just type the following command.

>nvm use v12.X.XX


问:
Dynamic combobox javascript
I am trying to make a combobox in javascript and populate it from an array. On selection I want to change a variable, call a function etc. I have looked at multiple tutorials on-line but for such an easy task the tutorials are dire.

Can anyone help?
Cheers

答:
```<code>var i, theContainer, theSelect, theOptions, numOptions, anOption;
theOptions = ['option 1','option 2','option 3'];

// Create the container <div>
theContainer = document.createElement('div');
theContainer.id = 'my_new_div';

// Create the <select>
theSelect = document.createElement('select');

// Give the <select> some attributes
theSelect.name = 'name_of_select';
theSelect.id = 'id_of_select';
theSelect.className = 'class_of_select';

// Define something to do onChange
theSelect.onchange = function () {
    // Do whatever you want to do when the select changes
    alert('You selected option '+this.selectedIndex);
};

// Add some <option>s
numOptions = theOptions.length;
for (i = 0; i < numOptions; i++) {
    anOption = document.createElement('option');
    anOption.value = i;
    anOption.innerHTML = theOptions[i];
    theSelect.appendChild(anOption);
}

// Add the <div> to the DOM, then add the <select> to the <div>
document.getElementById('container_for_select_container').appendChild(theContainer);
theContainer.appendChild(theSelect);
</code>```

ContentLicense: CC BY-SA 3.0

Title: Dynamic combobox javascript


问:
ASP.NET MVC - Getting QueryString values
Under ASP.NET MVC are you supposed to pick up QueryString params the same way you do in ASP.NET WebForms? or does the [AcceptVerbs(HttpVerbs.Get)] declaration get used somehow?

答:
This is the correct way in .NET 6 (and other netcore)

var Param = Request.Query["IndexString"];

If need to be string

string Param = Request.Query["IndexString"].ToString();

OwnerDisplayName: Bruno Tyndall


问:
Pinescript - Simple if else
I am currently trying to get back into coding (its been some time) and for some reason I cant get my pinescipt to execute properly.

The intent is that

Condition for strategy execution is met, on the first candle a particular strategy.entry with alert_message is executed (3commas deal start).

On the next candle, or any subsequent candle WHILE the deal is open, if the same condition is met a second strategy.entry and alert_message is executed (3commas deal add funds)

If following these the event is NOT met, strategy close is triggered.

At the moment, for some reason its only triggering the deal start repeatedly, and not jumping to the add - I know its a dumb mistake - I just cant see it!!!

```<code>base_Long_Order_Placed = 0

message_long_entry = "3commas deal start"
message_long_addition = "3commas deal add funds"
message_long_exit = "3commas close all deals"

longCondition = SECRET_SAUCE

if (longCondition == true and base_Long_Order_Placed == 0)
    strategy.entry('Long', strategy.long, when = longCondition ==true and barstate.isconfirmed, alert_message = message_long_entry) /
    base_Long_Order_Placed := 1
else if (longCondition == true and base_Long_Order_Placed == 1)
    strategy.entry('Long', strategy.long, when = base_Long_Order_Placed == 1 and longCondition ==true and barstate.isconfirmed, alert_message = message_long_addition)
else if (longCondition == false)
    strategy.close('Long', when=longCondition == false and barstate.isconfirmed, alert_message = message_long_exit)
    base_Long_Order_Placed := 0
else
    na
</code>```

答:
Your script will be executed on every bar. When you define a variable like below

base_Long_Order_Placed = 0

It will be re-defined every time and base_Long_Order_Placed == 0 will always be true. If you want to keep its value between executions, you need to use the var keyword.

var base_Long_Order_Placed = 0

Edit

var is just a keyword that tells the compiler to keep its value for the next execution. It is just a regular variable otherwise. It will keep its value unless you overwrite. It will not iterate unless you do

```<code>base_Long_Order_Placed := base_Long_Order_Placed  + 1
</code>```

So, you can definitely reset it when your condition is met.

```<code>if (deal_closed)
    base_Long_Order_Placed := 0
</code>```

Title: Pinescript - Simple if else

Body:
I am currently trying to get back into coding (its been some time) and for some reason I cant get my pinescipt to execute properly.

The intent is that

Condition for strategy execution is met, on the first candle a particular strategy.entry with alert_message is executed (3commas deal start).

On the next candle, or any subsequent candle WHILE the deal is open, if the same condition is met a second strategy.entry and alert_message is executed (3commas deal add funds)

If following these the event is NOT met, strategy close is triggered.

At the moment, for some reason its only triggering the deal start repeatedly, and not jumping to the add - I know its a dumb mistake - I just cant see it!!!

base_Long_Order_Placed = 0

message_long_entry = "3commas deal start"
message_long_addition = "3commas deal add funds"
message_long_exit = "3commas close all deals"

longCondition = SECRET_SAUCE

if (longCondition == true and base_Long_Order_Placed == 0)
    strategy.entry('Long', strategy.long, when = longCondition ==true and barstate.isconfirmed, alert_message = message_long_entry) /
    base_Long_Order_Placed := 1
else if (longCondition == true and base_Long_Order_Placed == 1)
    strategy.entry('Long', strategy.long, when = base_Long_Order_Placed == 1 and longCondition ==true and barstate.isconfirmed, alert_message = message_long_addition)
else if (longCondition == false)
    strategy.close('Long', when=longCondition == false and barstate.isconfirmed, alert_message = message_long_exit)
    base_Long_Order_Placed := 0
else
    na

Body:
Your script will be executed on every bar. When you define a variable like below

base_Long_Order_Placed = 0

It will be re-defined every time and base_Long_Order_Placed == 0 will always be true. If you want to keep its value between executions, you need to use the var keyword.

var base_Long_Order_Placed = 0

Edit

var is just a keyword that tells the compiler to keep its value for the next execution. It is just a regular variable otherwise. It will keep its value unless you overwrite. It will not iterate unless you do

base_Long_Order_Placed := base_Long_Order_Placed  + 1

So, you can definitely reset it when your condition is met.

if (deal_closed)
    base_Long_Order_Placed := 0


问:
python method as argument
So I know in python everything is an 'object' meaning that it can be passed as an argument to a method. But I'm trying to understand how exactly does this work. So I was trying out the following example:

```<code>class A:

    def __init__(self):
        self.value = 'a'

    def my_method(self)
        print self.value

class B:

   def __init__(self):
       self.values = 'b'

   def my_method(self, method):
       method()

a = A()
b = B()
b.my_method(a.my_method)
</code>```

Now first this was written just to see how things work. I know I should for example check if my_method 's argument is callable. Now my question is:

How exactly is the method passed here? I mean the output I'm recieving is 'a' so I'm guessing that when a object method is passed as parameter so is the actual object ? In this case when I pass a.my_method the instance a is also passed ?

答:
How exactly is the method passed here?

This is easily answered: in Python, everything is an object :) Also functions/methods, which are specific function objects which can be passed as parameters.

In this case when I pass a.my_method the instance a is also passed?

Yes, in this case the instance a is also passed, though embedded in the function object and cannot be retrieved. On the contrary you could pass the function itself and supply it with an instance. Consider the following example:

```<code>b = B()
func = A.my_method # Attention, UPPERCASE A
func(b)
</code>```

This would call the A classes method my_method with an instance of B.

Title: python method as argument

Body:
So I know in python everything is an 'object' meaning that it can be passed as an argument to a method. But I'm trying to understand how exactly does this work. So I was trying out the following example:

class A:

    def __init__(self):
        self.value = 'a'

    def my_method(self)
        print self.value

class B:

   def __init__(self):
       self.values = 'b'

   def my_method(self, method):
       method()

a = A()
b = B()
b.my_method(a.my_method)

Now first this was written just to see how things work. I know I should for example check if my_method 's argument is callable. Now my question is:

How exactly is the method passed here? I mean the output I'm recieving is 'a' so I'm guessing that when a object method is passed as parameter so is the actual object ? In this case when I pass a.my_method the instance a is also passed ?

Body:
How exactly is the method passed here?

This is easily answered: in Python, everything is an object :) Also functions/methods, which are specific function objects which can be passed as parameters.

In this case when I pass a.my_method the instance a is also passed?

Yes, in this case the instance a is also passed, though embedded in the function object and cannot be retrieved. On the contrary you could pass the function itself and supply it with an instance. Consider the following example:

b = B()
func = A.my_method # Attention, UPPERCASE A
func(b)

This would call the A classes method my_method with an instance of B.


问:
How can I use strtok() and getline() to read the lines of a file into a linked list?
```<code>#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node {
     char *name;
     struct node *next;
};

typedef struct node LINK;
struct node *head;
head = NULL;

int main(int argv, char **argc){

    // struct node *head, *current;
    //open the file
    int size;

    //for the strtok()
    const char space[1] = " ";
    //char *name;
    char *code;

    //for the getline()
    char *line;
    line = (char *)malloc(size);

    //number of characters in each line of file
    int oneline;

    FILE *fO;
    fO = fopen("hw5.data", "r");

    //check if file is not opening
    if(fO == NULL){
        printf("********************************************\n");
        printf("You must include a filename to load.\n");
        printf("********************************************\n");
    }

    //read the file data into the linked list
    int x = 0;
    while(getline(&line, &size, fO) != -1){
        char *name = strtok(line, " ");
        strtok(NULL, " ");
        printf("Here is the name %s \n", name);

        name = strtok(NULL, " ");
        printf("here's the code for name %s\n", name);

        x++;
        free(name);
    }

    free(line);
    //free(name);
    return 0;
}
</code>```

I need to use strtok() and getline() to read a file with a format of a name, 1 space and a single character per line like "Edward a" or "Bella d".  This program returns:

Heres the name Edward
here's the code for name (null)
```
<p>instead of "(null)" I was hoping it would return 'a'.</p>
<p>I have read the man page for <code>strtok()</code> and <code>getline()</code>; I am still confused about it.  Does anyone know what the problem is? Sorry, I'm just required to use <code>strtok()</code> and <code>getline()</code>.</p>
<hr />
<p>Here is the function I was talking about actually, I was trying to sort the linked list of strings with the strcmp(), to accordingly place the new string into the linked list. If the LinkedList was empty then Edward could be added. Otherwise, I tried to compare the input char name[] to the existing strings to put it in its place in ascending order.</p>
```//function to search list
int LIST_SEARCH(char name[], LINK *head) {
    LINK *current;
    current = head;
    while (current != NULL) {
       if (!strcmp(current->name, name)){
           current = current->next;
           printf(" here it is 1.\n");
           printf("\n");
           return 1;
       }

   }
   printf("Did not find it.\n");
   printf("\n");

   return 0;
}

LINK *LIST_INSERT(char name[], LINK *head) {
    LINK *current, *temp1;
    if (LIST_SEARCH(name, head) == 1){
        return head;
    }

    temp1 = (LINK *)malloc(sizeof(LINK));
    strcpy(temp1->name, name);

    //test if the list is empty.
    if (head == NULL) {
        printf("empty\n");
        head = temp1;
        temp1->next = NULL;
        return head;
    }

    //add the string to front of the list
    current = head;
    if(strcmp(current->name, name) > 0){
        printf("add name to front: %s\n", name);
        temp1->next  = current;
        head = temp1;
        return head;
    }
    //put the string at the back or middle of list
    current = head;
    while (current != NULL) {

       if (current->next == NULL || strcmp(current->next->name, name) > 0){
           printf("add name elsewhere: %s\n", name);
           temp1->next    = current->next;
           current->next = temp1;
           return head;
       }
        //iterate
       current = current->next;
    }
}
```

The function seemed to have added the first name. However, for the rest of the names, it does not execute the print statements and the program does not finish. It does not give errors either.

答:
You have the code:

```<code>char *name = strtok(line, " ");
strtok(NULL, " ");
</code>```

You can't afford to discard the result of the second call to strtok() like that — it contains the pointer to the code.  Remove that line!

There are other problems too.  You don't initialize size; it should be of type size_t anyway.  You have unused extraneous code in the question too.  You check whether the file was opened (though the message is a bit odd); that's good.  However, you continue to use the unopened file; that's bad.  You should report the error on standard error, not standard output.  It would be good to include the file name in the message.  It would be a good idea to zap the newline after reading the line.  You should not call free(name).  The space allocated by getline() is pointed at by line, and you should (and do) call free(line) when the input loop completes.  The value returned by strtok() should not be freed; it does not allocate space, and the pointer returned is not guaranteed to the pointer returned by malloc().

Here's working code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    size_t size = 0;
    char *line = 0;
    const char *filename = "hw5.data";
    FILE *fO = fopen(filename, "r");

    if (fO == NULL)
    {
        fprintf(stderr, "Failed to open file %s for reading\n", filename);
        exit(EXIT_FAILURE);
    }

    while (getline(&line, &size, fO) != -1)
    {
        line[strcspn(line, "\n\r")] = '\0';
        char *name = strtok(line, " ");
        char *code = strtok(NULL, " ");
        printf("Here is the name '%s'\n", name);
        printf("here's the code for name '%s'\n", code);
    }

    free(line);
    return 0;
}
```
<p>For the described input, it yields:</p>
<pre class="lang-none prettyprint-override"><code>Here is the name 'Edward'
here's the code for name 'a'
Here is the name 'Bella'
here's the code for name 'd'
</code>```

Note that when you get around to adding the data to your linked list, you'll need to duplicate the strings found — use strdup().

Here is some code which creates, prints and releases a linked list using strdup() to copy the name.  Since the structure in the question has no place for storing the code, the code is printed while reading the data but otherwise ignored.  Note that I renamed the structure tag to Node, and used the tag as the typedef name too.  Also, note that there are no global (file scope) variables; you should avoid them as often as possible, which is most of the time.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Node Node;
struct Node
{
    char *name;
    Node *next;
};

static Node *new_node(Node *head, const char *name)
{
    Node *np = malloc(sizeof(*np));
    if (np == NULL)
    {
        fprintf(stderr, "Failed to allocate %zu bytes of memory\n", sizeof(*np));
        exit(EXIT_FAILURE);
    }
    np->name = strdup(name);
    if (np->name == NULL)
    {
        fprintf(stderr, "Failed to allocate %zu bytes of memory\n", strlen(name) + 1);
        exit(EXIT_FAILURE);
    }
    np->next = head;
    return np;
}

static void print_list(const Node *head)
{
    const Node *curr = head;
    size_t count = 0;
    while (curr != NULL)
    {
        printf("%zu: [%s]\n", ++count, curr->name);
        curr = curr->next;
    }
}

static void free_list(Node *head)
{
    Node *curr = head;
    while (curr != NULL)
    {
        Node *next = curr->next;
        free(curr->name);
        free(curr);
        curr = next;
    }
}

int main(void)
{
    const char *filename = "hw5.data";
    FILE *fO = fopen(filename, "r");

    if (fO == NULL)
    {
        fprintf(stderr, "Failed to open file %s for reading\n", filename);
        exit(EXIT_FAILURE);
    }

    Node *head = NULL;

    size_t size = 0;
    char *line = NULL;
    while (getline(&line, &size, fO) != -1)
    {
        line[strcspn(line, "\n\r")] = '\0';
        char *name = strtok(line, " ");
        char *code = strtok(NULL, " ");
        printf("Here is the name '%s'\n", name);
        printf("Here is the code '%s'\n", code);
        head = new_node(head, name);
    }
    free(line);

    print_list(head);
    free_list(head);

    return 0;
}
```
<p>I used this as the data file <code>hw5.data</code>:</p>
<pre class="lang-none prettyprint-override"><code>Edward a
Bella d
Jacob a
Renesmee b
Jasper c
Rosalie b
Alice a
Carlisle a
</code>```

The output from the program is then:

Here is the name 'Edward'
Here is the code 'a'
Here is the name 'Bella'
Here is the code 'd'
Here is the name 'Jacob'
Here is the code 'a'
Here is the name 'Renesmee'
Here is the code 'b'
Here is the name 'Jasper'
Here is the code 'c'
Here is the name 'Rosalie'
Here is the code 'b'
Here is the name 'Alice'
Here is the code 'a'
Here is the name 'Carlisle'
Here is the code 'a'
1: [Carlisle]
2: [Alice]
3: [Rosalie]
4: [Jasper]
5: [Renesmee]
6: [Jacob]
7: [Bella]
8: [Edward]
```

I use quotes and square brackets around the names to demonstrate that there are no extraneous characters.

Body:
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node {
     char *name;
     struct node *next;
};

typedef struct node LINK;
struct node *head;
head = NULL;

int main(int argv, char **argc){

    // struct node *head, *current;
    //open the file
    int size;

    //for the strtok()
    const char space[1] = " ";
    //char *name;
    char *code;

    //for the getline()
    char *line;
    line = (char *)malloc(size);

    //number of characters in each line of file
    int oneline;

    FILE *fO;
    fO = fopen("hw5.data", "r");

    //check if file is not opening
    if(fO == NULL){
        printf("********************************************\n");
        printf("You must include a filename to load.\n");
        printf("********************************************\n");
    }

    //read the file data into the linked list
    int x = 0;
    while(getline(&line, &size, fO) != -1){
        char *name = strtok(line, " ");
        strtok(NULL, " ");
        printf("Here is the name %s \n", name);

        name = strtok(NULL, " ");
        printf("here's the code for name %s\n", name);

        x++;
        free(name);
    }

    free(line);
    //free(name);
    return 0;
}

I need to use strtok() and getline() to read a file with a format of a name, 1 space and a single character per line like "Edward a" or "Bella d".  This program returns:

Heres the name Edward
here's the code for name (null)

instead of "(null)" I was hoping it would return 'a'.

I have read the man page for strtok() and getline(); I am still confused about it.  Does anyone know what the problem is? Sorry, I'm just required to use strtok() and getline().

Here is the function I was talking about actually, I was trying to sort the linked list of strings with the strcmp(), to accordingly place the new string into the linked list. If the LinkedList was empty then Edward could be added. Otherwise, I tried to compare the input char name[] to the existing strings to put it in its place in ascending order.

//function to search list
int LIST_SEARCH(char name[], LINK *head) {
    LINK *current;
    current = head;
    while (current != NULL) {
       if (!strcmp(current->name, name)){
           current = current->next;
           printf(" here it is 1.\n");
           printf("\n");
           return 1;
       }

   }
   printf("Did not find it.\n");
   printf("\n");

   return 0;
}

LINK *LIST_INSERT(char name[], LINK *head) {
    LINK *current, *temp1;
    if (LIST_SEARCH(name, head) == 1){
        return head;
    }

    temp1 = (LINK *)malloc(sizeof(LINK));
    strcpy(temp1->name, name);

    //test if the list is empty.
    if (head == NULL) {
        printf("empty\n");
        head = temp1;
        temp1->next = NULL;
        return head;
    }

    //add the string to front of the list
    current = head;
    if(strcmp(current->name, name) > 0){
        printf("add name to front: %s\n", name);
        temp1->next  = current;
        head = temp1;
        return head;
    }
    //put the string at the back or middle of list
    current = head;
    while (current != NULL) {

       if (current->next == NULL || strcmp(current->next->name, name) > 0){
           printf("add name elsewhere: %s\n", name);
           temp1->next    = current->next;
           current->next = temp1;
           return head;
       }
        //iterate
       current = current->next;
    }
}

The function seemed to have added the first name. However, for the rest of the names, it does not execute the print statements and the program does not finish. It does not give errors either.

Body:
You have the code:

char *name = strtok(line, " ");
strtok(NULL, " ");

You can't afford to discard the result of the second call to strtok() like that — it contains the pointer to the code.  Remove that line!

There are other problems too.  You don't initialize size; it should be of type size_t anyway.  You have unused extraneous code in the question too.  You check whether the file was opened (though the message is a bit odd); that's good.  However, you continue to use the unopened file; that's bad.  You should report the error on standard error, not standard output.  It would be good to include the file name in the message.  It would be a good idea to zap the newline after reading the line.  You should not call free(name).  The space allocated by getline() is pointed at by line, and you should (and do) call free(line) when the input loop completes.  The value returned by strtok() should not be freed; it does not allocate space, and the pointer returned is not guaranteed to the pointer returned by malloc().

Here's working code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    size_t size = 0;
    char *line = 0;
    const char *filename = "hw5.data";
    FILE *fO = fopen(filename, "r");

    if (fO == NULL)
    {
        fprintf(stderr, "Failed to open file %s for reading\n", filename);
        exit(EXIT_FAILURE);
    }

    while (getline(&line, &size, fO) != -1)
    {
        line[strcspn(line, "\n\r")] = '\0';
        char *name = strtok(line, " ");
        char *code = strtok(NULL, " ");
        printf("Here is the name '%s'\n", name);
        printf("here's the code for name '%s'\n", code);
    }

    free(line);
    return 0;
}

For the described input, it yields:

Here is the name 'Edward'
here's the code for name 'a'
Here is the name 'Bella'
here's the code for name 'd'

Note that when you get around to adding the data to your linked list, you'll need to duplicate the strings found — use strdup().

Here is some code which creates, prints and releases a linked list using strdup() to copy the name.  Since the structure in the question has no place for storing the code, the code is printed while reading the data but otherwise ignored.  Note that I renamed the structure tag to Node, and used the tag as the typedef name too.  Also, note that there are no global (file scope) variables; you should avoid them as often as possible, which is most of the time.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Node Node;
struct Node
{
    char *name;
    Node *next;
};

static Node *new_node(Node *head, const char *name)
{
    Node *np = malloc(sizeof(*np));
    if (np == NULL)
    {
        fprintf(stderr, "Failed to allocate %zu bytes of memory\n", sizeof(*np));
        exit(EXIT_FAILURE);
    }
    np->name = strdup(name);
    if (np->name == NULL)
    {
        fprintf(stderr, "Failed to allocate %zu bytes of memory\n", strlen(name) + 1);
        exit(EXIT_FAILURE);
    }
    np->next = head;
    return np;
}

static void print_list(const Node *head)
{
    const Node *curr = head;
    size_t count = 0;
    while (curr != NULL)
    {
        printf("%zu: [%s]\n", ++count, curr->name);
        curr = curr->next;
    }
}

static void free_list(Node *head)
{
    Node *curr = head;
    while (curr != NULL)
    {
        Node *next = curr->next;
        free(curr->name);
        free(curr);
        curr = next;
    }
}

int main(void)
{
    const char *filename = "hw5.data";
    FILE *fO = fopen(filename, "r");

    if (fO == NULL)
    {
        fprintf(stderr, "Failed to open file %s for reading\n", filename);
        exit(EXIT_FAILURE);
    }

    Node *head = NULL;

    size_t size = 0;
    char *line = NULL;
    while (getline(&line, &size, fO) != -1)
    {
        line[strcspn(line, "\n\r")] = '\0';
        char *name = strtok(line, " ");
        char *code = strtok(NULL, " ");
        printf("Here is the name '%s'\n", name);
        printf("Here is the code '%s'\n", code);
        head = new_node(head, name);
    }
    free(line);

    print_list(head);
    free_list(head);

    return 0;
}

I used this as the data file hw5.data:

Edward a
Bella d
Jacob a
Renesmee b
Jasper c
Rosalie b
Alice a
Carlisle a

The output from the program is then:

Here is the name 'Edward'
Here is the code 'a'
Here is the name 'Bella'
Here is the code 'd'
Here is the name 'Jacob'
Here is the code 'a'
Here is the name 'Renesmee'
Here is the code 'b'
Here is the name 'Jasper'
Here is the code 'c'
Here is the name 'Rosalie'
Here is the code 'b'
Here is the name 'Alice'
Here is the code 'a'
Here is the name 'Carlisle'
Here is the code 'a'
1: [Carlisle]
2: [Alice]
3: [Rosalie]
4: [Jasper]
5: [Renesmee]
6: [Jacob]
7: [Bella]
8: [Edward]

I use quotes and square brackets around the names to demonstrate that there are no extraneous characters.


问:
jQuery - thousands seperator on html string
I'm trying to add a thousands separator for the .htm(price * num) result by adding .digits(); to the var sub. How do I get the thousands seperator to work on the result of the var sub? Since they are not val do I need to convert the result into a number before adding the digits(); function?

$(document).ready(function() {
  $.fn.digits = function() {
    return this.each(function() {
      $(this).val(
        $(this)
        .val()
        .replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")
      );
    });
  };
  var total = $(".slider__total").html();
  var sold = $(".sold").html();
  var available = total - sold;
  var price = $(".cost").html();
  var num = $("#num").html();
  $(".item__available").html(available);
  var sub = $("#slider_subtotal")
    .html(price * num)
    .digits();
  $(".qty").attr({
    max: available
  });
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
sold<span class="sold">3</span>total<span class="slider__total">10</span>available<span class="item__available"></span><input type="range" min="1" value="1" class="qty" name='quantity' oninput="num.value = this.value"><output id="num">0</output>unit:
$
<span class="cost">500</span>subtotal: $<span id="slider_subtotal">0</span></code>```

答:
You could use the built-in Number.prototype.toLocaleString() method instead:

```<code>(1234567.567).toLocaleString('en-US') // 1,234,567.567
</code>```

Or - if you prefer - you can also keep it "local" to the current user by omitting the first argument: (1234567.567).toLocaleString() will refer to the browsers regional settings and will return a suitable local number string.

$(document).ready(function() {
  var total = $(".slider__total").text();
  var sold = $(".sold").text();
  var available = total - sold;
  var price = $(".cost").text();

  $(".item__available").html(available);
  $(".qty").attr({max: available})
           .on("input",function(){
    $("#slider_subtotal").text((price * this.value).toLocaleString("en-US",{style:'currency', currency:'USD'}));
    $("#num").text(this.value)
  });
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
sold<span class="sold">37</span>
total<span class="slider__total">103</span>
available<span class="item__available"></span>
<input type="range" min="1" value="1" class="qty" name='quantity'>
<output id="num">0</output>
unit:$<span class="cost">123.4</span>
subtotal: <span id="slider_subtotal">$0</span></code>```

Body:
I'm trying to add a thousands separator for the .htm(price * num) result by adding .digits(); to the var sub. How do I get the thousands seperator to work on the result of the var sub? Since they are not val do I need to convert the result into a number before adding the digits(); function?

$(document).ready(function() {
  $.fn.digits = function() {
    return this.each(function() {
      $(this).val(
        $(this)
        .val()
        .replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")
      );
    });
  };
  var total = $(".slider__total").html();
  var sold = $(".sold").html();
  var available = total - sold;
  var price = $(".cost").html();
  var num = $("#num").html();
  $(".item__available").html(available);
  var sub = $("#slider_subtotal")
    .html(price * num)
    .digits();
  $(".qty").attr({
    max: available
  });
});

sold3total10available<input type="range" min="1" value="1" class="qty" name='quantity' oninput="num.value = this.value"><output id="num">0</output>unit:
$
500subtotal: $0

Body:
You could use the built-in Number.prototype.toLocaleString() method instead:

(1234567.567).toLocaleString('en-US') // 1,234,567.567

Or - if you prefer - you can also keep it "local" to the current user by omitting the first argument: (1234567.567).toLocaleString() will refer to the browsers regional settings and will return a suitable local number string.

$(document).ready(function() {
  var total = $(".slider__total").text();
  var sold = $(".sold").text();
  var available = total - sold;
  var price = $(".cost").text();

  $(".item__available").html(available);
  $(".qty").attr({max: available})
           .on("input",function(){
    $("#slider_subtotal").text((price * this.value).toLocaleString("en-US",{style:'currency', currency:'USD'}));
    $("#num").text(this.value)
  });
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
sold<span class="sold">37</span>
total<span class="slider__total">103</span>
available<span class="item__available"></span>
<input type="range" min="1" value="1" class="qty" name='quantity'>
<output id="num">0</output>
unit:$<span class="cost">123.4</span>
subtotal: <span id="slider_subtotal">$0</span>


问:
Timetable week view in Flutter
I want to create a week view of a timetable.
I don't want a calendar week but I want a week like in school.
The data (events and description) need to be variable, not constant.
A method to get a view similar to the one in the following picture would be great, a simpler one would be appreciated too.

答: You may use calendar_view package. You can achieve your output by using week view mentioned in the package.</p>

Title: Timetable week view in Flutter


问:
R+Tidyverse: Tibbles don't appear to store milliseconds
I have a CSV with many values. Among them are times stored like this:

```<code>1:34.434
</code>```

Using readr, I form them into a tibble, and use dplyr to cut out all the unnecessary rows and columns.

```<code>lapData <- read_csv("sampledata/sampledata.csv")
lapData <- dplyr::select(lapData,
                         Driver, Lap, Penalty, 'Lap Time', 'Lap type',
                         'Pressure FR', 'Pressure FL', 'Pressure RR', 'Pressure RL',
                         'Temp FR', 'Temp FL', 'Temp RR', 'Temp RL',
                         'Road Temp')
lapData <- dplyr::filter(lapData, Driver == "[personal info]")
lapData <- dplyr::filter(lapData, is.na(Penalty))
lapData <- dplyr::filter(lapData, Lap > 1)
</code>```

I then use print(ggplot(data = lapData, mapping = aes(Lap, 'Lap Time')) + geom_line()) to print the data, and it looks like this:

If it isn't clear, the vertices of the graph line are rounded to the seconds value instead of using the full milisecond precision, which I would like to have.

If I then print(lapData), I see the following entries under 'Lap Time':

I did some research, and found this, which seems to indicate that the loss of precision in the printout from the tibble is inconsequential, and the full data is still stored in the tibble. However, the plot contradicts this statement.

How do I get the plot to show the full millisecond resolution?

答:
To avoid readr's guessing, you could use conventional read.csv.

```<code>r <- read.csv('foo.csv')
</code>```

Next, it is probably better to use pure milliseconds. For this, we may use strptime with"%M:%OS" which returns the beautiful "POSIXlt" format that we can put in a with and play with the minutes and seconds.

```<code>r$lap_time_ms <- with(strptime(r$lap_time, format="%M:%OS"), 6e4*min + 1e3*sec)

r
#   lap_time lap          x lap_time_ms
# 1 1:29.134   1  0.9292880       89134
# 2 1:26.233   2 -0.3301566       86233
# 3 1:28.033   3 -1.5426225       88033
# 4 1:26.434   4 -0.9961375       86434
# 5 1:26.634   5  1.1610645       86634
# 6 1:27.634   6 -0.2817558       87634
</code>```

If you want a y-axis formatted in <secs>:<mins> format, use a sequence along the range of the lap times with steps in seconds.

```<code>at <- do.call(seq, c(as.list(range(ceiling(r$lap_time_ms/1e3))*1e3), 1e3))
sq <- at %/% 1e3 |> {\(.) paste(. %/% 60, . %% 60, sep=':')}()

plot(lap_time_ms ~ lap, r, type='l', yaxt='n')
axis(2, at=at, labels=sq)
</code>```

This should also be possible with ggplot2 package.

Data:

```<code>dat <- read.table(header=TRUE, text='lap_time
1:29.134
1:26.233
1:28.033
1:26.434
1:26.634
1:27.634
') |> transform(lap=1:6, x=rnorm(6))
write.csv(dat, 'foo.csv', row.names=FALSE)
</code>```

Body:
I have a CSV with many values. Among them are times stored like this:

1:34.434

Using readr, I form them into a tibble, and use dplyr to cut out all the unnecessary rows and columns.

lapData <- read_csv("sampledata/sampledata.csv")
lapData <- dplyr::select(lapData,
                         Driver, Lap, Penalty, 'Lap Time', 'Lap type',
                         'Pressure FR', 'Pressure FL', 'Pressure RR', 'Pressure RL',
                         'Temp FR', 'Temp FL', 'Temp RR', 'Temp RL',
                         'Road Temp')
lapData <- dplyr::filter(lapData, Driver == "[personal info]")
lapData <- dplyr::filter(lapData, is.na(Penalty))
lapData <- dplyr::filter(lapData, Lap > 1)

I then use print(ggplot(data = lapData, mapping = aes(Lap, 'Lap Time')) + geom_line()) to print the data, and it looks like this:

If it isn't clear, the vertices of the graph line are rounded to the seconds value instead of using the full milisecond precision, which I would like to have.

If I then print(lapData), I see the following entries under 'Lap Time':

I did some research, and found this, which seems to indicate that the loss of precision in the printout from the tibble is inconsequential, and the full data is still stored in the tibble. However, the plot contradicts this statement.

How do I get the plot to show the full millisecond resolution?

Body:
To avoid readr's guessing, you could use conventional read.csv.

r <- read.csv('foo.csv')

Next, it is probably better to use pure milliseconds. For this, we may use strptime with"%M:%OS" which returns the beautiful "POSIXlt" format that we can put in a with and play with the minutes and seconds.

r$lap_time_ms <- with(strptime(r$lap_time, format="%M:%OS"), 6e4*min + 1e3*sec)

r
#   lap_time lap          x lap_time_ms
# 1 1:29.134   1  0.9292880       89134
# 2 1:26.233   2 -0.3301566       86233
# 3 1:28.033   3 -1.5426225       88033
# 4 1:26.434   4 -0.9961375       86434
# 5 1:26.634   5  1.1610645       86634
# 6 1:27.634   6 -0.2817558       87634

If you want a y-axis formatted in <secs>:<mins> format, use a sequence along the range of the lap times with steps in seconds.

at <- do.call(seq, c(as.list(range(ceiling(r$lap_time_ms/1e3))*1e3), 1e3))
sq <- at %/% 1e3 |> {\(.) paste(. %/% 60, . %% 60, sep=':')}()

plot(lap_time_ms ~ lap, r, type='l', yaxt='n')
axis(2, at=at, labels=sq)

This should also be possible with ggplot2 package.

Data:

dat <- read.table(header=TRUE, text='lap_time
1:29.134
1:26.233
1:28.033
1:26.434
1:26.634
1:27.634
') |> transform(lap=1:6, x=rnorm(6))
write.csv(dat, 'foo.csv', row.names=FALSE)


问:
Python Library for LSM303D 6-Axis Accelerometer / Compass V2.0: unexpected results
I recently acquired a Grove Sensor board for the LSM303D 6-Axis Accelerometer / Compass. Unfortunately, it transpired that the device did not yet have a Python library (only a C++ library and Arduino .ino file).

I am attempting to use it with the GrovePi+ board with Raspberry Pi, and would like to use it with Python code, so I made an attempt to transcribe the C++ Code into Python. However, I am getting odd output.

Additional information relating to the device can be found on the Pololu Datasheet

sudo i2cdetect -y 1 shows the device can be found at address 0x1E

```
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- 04 -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
```

Here is the Python Code:

```<code>#!/usr/bin.env python

import smbus
import time
import math
import RPi.GPIO as GPIO
import struct

rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
    bus = smbus.SMBus(1)
else:
    bus = smbus.SMBus(0)

### LSM303 Address ###
LSM303D_ADDR    = 0x1E # Assuming SA0 grounded

### LSM303 Register definitions ###
TEMP_OUT_L      = 0x05
TEMP_OUT_H      = 0x06
STATUS_REG_M    = 0x07
OUT_X_L_M       = 0x08
OUT_X_H_M       = 0x09
OUT_Y_L_M       = 0x0A
OUT_Y_H_M       = 0x0B
OUT_Z_L_M       = 0x0C
OUT_Z_H_M       = 0x0D
WHO_AM_I        = 0x0F
INT_CTRL_M      = 0x12
INT_SRC_M       = 0x13
INT_THS_L_M     = 0x14
INT_THS_H_M     = 0x15
OFFSET_X_L_M    = 0x16
OFFSET_X_H_M    = 0x17
OFFSET_Y_L_M    = 0x18
OFFSET_Y_H_M    = 0x19
OFFSET_Z_L_M    = 0x1A
OFFSET_Z_H_M    = 0x1B
REFERENCE_X     = 0x1C
REFERENCE_Y     = 0x1D
REFERENCE_Z     = 0x1E
CTRL_REG0       = 0x1F
CTRL_REG1       = 0x20
CTRL_REG2       = 0x21
CTRL_REG3       = 0x22
CTRL_REG4       = 0x23
CTRL_REG5       = 0x24
CTRL_REG6       = 0x25
CTRL_REG7       = 0x26
STATUS_REG_A    = 0x27
OUT_X_L_A       = 0x28
OUT_X_H_A       = 0x29
OUT_Y_L_A       = 0x2A
OUT_Y_H_A       = 0x2B
OUT_Z_L_A       = 0x2C
OUT_Z_H_A       = 0x2D
FIFO_CTRL       = 0x2E
FIFO_SRC        = 0x2F
IG_CFG1         = 0x30
IG_SRC1         = 0x31
IG_THS1         = 0x32
IG_DUR1         = 0x33
IG_CFG2         = 0x34
IG_SRC2         = 0x35
IG_THS2         = 0x36
IG_DUR2         = 0x37
CLICK_CFG       = 0x38
CLICK_SRC       = 0x39
CLICK_THS       = 0x3A
TIME_LIMIT      = 0x3B
TIME_LATENCY    = 0x3C
TIME_WINDOW     = 0x3D
ACT_THS         = 0x3E
ACT_DUR         = 0x3F

### Mag scales ###
MAG_SCALE_2     = 0x00 # full-scale is +/- 2 Gauss
MAG_SCALE_4     = 0x20 # +/- 4 Guass
MAG_SCALE_8     = 0x40 # +/- 8 Guass
MAG_SCALE_12    = 0x60 # +/- 12 Guass

ACCEL_SCALE     = 2 # +/- 2g

X = 0
Y = 1
Z = 2

def twos_comp(val, bits):
    # Calculate the 2s complement of int:val #
    if(val&(1<<(bits-1)) != 0):
        val = val - (1<<bits)
    return val
#   return val if val < 32768 else val - 65536

class accelcomp:
    mag = [0,0,0]
    accel = [0,0,0]
    tiltcomp = [0,0,0]
    heading=0
    headingDegrees=0
    tiltHeading=0
    tiltHeadingDegrees=0

    def __init__(self):
        whoami = bus.read_byte_data(LSM303D_ADDR, WHO_AM_I)

        if(whoami == 0x49):
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG1, 0x57) # 0x57 = ODR=50hz, all accel axes on ## maybe 0x27 is Low Res?
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG2, (3<<6)|(0<<3)) # set full scale +/- 2g
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG3, 0x00) # no interrupt
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG4, 0x00) # no interrupt
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG5, (4<<2)) # 0x10 = mag 50Hz output rate
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG6, MAG_SCALE_2) # Magnetic Scale +/1 1.3 Guass
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG7, 0x00) # 0x00 continuous conversion mode

    def getMag(self):
        self.mag[X] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_X_H_M) << 8 |
                          bus.read_byte_data(LSM303D_ADDR, OUT_X_L_M), 16)
        self.mag[Y] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_Y_H_M) << 8 |
                          bus.read_byte_data(LSM303D_ADDR, OUT_Y_L_M), 16)
        self.mag[Z] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_Z_H_M) << 8 |
                          bus.read_byte_data(LSM303D_ADDR, OUT_Z_L_M), 16)

    def getAccel(self):
        accel = [0,0,0]
        accel[X] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_X_H_A) << 8 |
                           bus.read_byte_data(LSM303D_ADDR, OUT_X_L_A), 16)
        accel[Y] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_Y_H_A) << 8 |
                           bus.read_byte_data(LSM303D_ADDR, OUT_Y_L_A), 16)
        accel[Z] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_Z_H_A) << 8 |
                           bus.read_byte_data(LSM303D_ADDR, OUT_Z_L_A), 16)

        for i in range(X, Z+1):
            self.accel[i] = accel[i] / math.pow(2, 15) * ACCEL_SCALE

    def getHeading(self):
        self.heading = math.atan2(self.mag[X], self.mag[Y])

        if self.heading < 0:
            self.heading += 2*math.pi
        if self.heading > 2*math.pi:
            self.heading -= 2*math.pi

        self.headingDegrees = round(math.degrees(self.heading),2)

    def getTiltHeading(self):
        truncate = [0,0,0]
        for i in range(X, Z+1):
            truncate[i] = math.copysign(min(math.fabs(self.accel[i]), 1.0), self.accel[i])
        try:
            pitch = math.asin(-1*truncate[X])
            roll = math.asin(truncate[Y]/math.cos(pitch)) if abs(math.cos(pitch)) >= abs(truncate[Y]) else 0
            # set roll to zero if pitch approaches -1 or 1

            self.tiltcomp[X] = self.mag[X] * math.cos(pitch) + self.mag[Z] * math.sin(pitch)
            self.tiltcomp[Y] = self.mag[X] * math.sin(roll) * math.sin(pitch) + \
                               self.mag[Y] * math.cos(roll) - self.mag[Z] * math.sin(roll) * math.cos(pitch)
            self.tiltcomp[Z] = self.mag[X] * math.cos(roll) * math.sin(pitch) + \
                               self.mag[Y] * math.sin(roll) + \
                               self.mag[Z] * math.cos(roll) * math.cos(pitch)
            self.tiltHeading = math.atan2(self.tiltcomp[Y], self.tiltcomp[X])

            if self.tiltHeading < 0:
                self.tiltHeading += 2*math.pi
            if self.tiltHeading > 2*math.pi:
                self.heading -= 2*math.pi

            self.tiltHeadingDegrees = round(math.degrees(self.tiltHeading),2)

        except Exception:
            print "AccelX {}, AccelY {}".format(self.accel[X], self.accel[Y])
            print "TruncX {}, TruncY {}".format(truncate[X], truncate[Y])
            print "Pitch {}, cos(pitch) {}, Bool(cos(pitch)) {}".format(pitch, math.cos(pitch), bool(math.cos(pitch)))

    def isMagReady(self):
        temp =  bus.read_byte_data(LSM303D_ADDR, STATUS_REG_M) & 0x03

        return temp

    def update(self):

        self.getAccel()
        self.getMag()
        self.getHeading()
        self.getTiltHeading()

if __name__ == '__main__':

    from time import sleep

    lsm = accelcomp()

    print '     Accelerometer     ||        Compass        ||              Heading'
    print '   x   |   y   |   z   ||   x   |   y   |   z   ||       calc      | tilt corrected  |'
    while True:
        lsm.getAccel()
        while not bool(lsm.isMagReady()):
            print "Not Ready!"
            sleep(.01)
        lsm.getMag()
        lsm.getHeading()
        lsm.getTiltHeading()
        print '{0:.3f} |{1:.3f} |{2:.3f} ||{3:6} |{4:6} |{5:6} ||  {6:6} deg     |  {7:6} deg     |'.format(
                    lsm.accel[X], lsm.accel[Y], lsm.accel[Z], lsm.mag[X], lsm.mag[Y], lsm.mag[Z], lsm.headingDegrees, lsm.tiltHeadingDegrees)
        sleep(.5)
</code>```

Some sample output:

```
    Accelerometer     ||        Compass        ||              Heading
  x   |   y   |   z   ||   x   |   y   |   z   ||       calc      | tilt corrected  |
0.022 |-0.012 |1.056 ||   876 | -1119 |  5788 ||  141.94 deg     |  305.58 deg     |
0.027 |-0.011 |1.052 ||   919 | -1128 |  5826 ||  140.83 deg     |  305.62 deg     |
0.026 |-0.010 |1.053 ||   903 | -1108 |  5777 ||  140.82 deg     |  305.61 deg     |
0.024 |-0.009 |1.054 ||   914 | -1140 |  5790 ||  141.28 deg     |  305.57 deg     |
0.024 |-0.010 |1.056 ||   895 | -1122 |  5801 ||  141.42 deg     |  305.42 deg     |
0.024 |-0.010 |1.055 ||   905 | -1088 |  5747 ||  140.25 deg     |  306.69 deg     |
0.022 |-0.008 |1.057 ||   900 | -1106 |  5748 ||  140.86 deg     |  306.15 deg     |
```

One point that is obvious from the output displayed is that the acceleration in the Z direction is, sitting on the table, greater than 1g. It's close enough to be considered ok, although when tilted, both X and Y also go over 1g, which throws Math Errors with the asin function in getTiltHeading(), hence the truncation.

However, the real issue is with errors in the compass over a full rotation. I aligned the device north relative to the compass on my phone, and it gave a close value to 360 / 0 degrees. However, rotating it clockwise around the circle introduced errors that climbed up to about 30 degrees off the expected value around 255 degrees (near magnetic West).

Tabulated Experiment:

```
<b>Angle   Trial 1 Trial 2 Trial 3 Trial 4 AVERAGE  ERROR</b>
0       356.53  355.18  355.74  357.13  356.145  356.145
0       -3.47   -4.82   -4.26   -2.87   -3.855   -3.855
15      11.26   10.65   11.57   11.02   11.125   -3.875
30      30.29   30.82   30.74   30.29   30.535   0.535
45      40.24   40.32   39.95   39.93   40.11    -4.89
60      55.84   55.51   55.53   54.89   55.4425  -4.5575
75      67.23   67.42   68.46   68.23   67.835   -7.165
90      83.65   83.8    83.96   83.55   83.74    -6.26
105     101.11  100.91  100.13  100.66  100.7025 -4.2975
120     117.15  117.13  116.59  115.79  116.665  -3.335
135     125.92  125.56  125.19  126.14  125.702  -9.2975
150     142.74  142.44  142.94  142.56  142.67   -7.33
165     157.22  156.77  157.53  157.07  157.1475 -7.8525
180     171.97  171.61  172.17  172.26  172.0025 -7.9975
195     183.81  183.47  182.99  183.39  183.415  -11.585
210     195.59  196.6   197.2   197.58  196.7425 -13.2575
225     210.07  210.59  209.47  210.21  210.085  -14.915
240     218.97  219.3   219.53  219.48  219.32   -20.68
255     226.13  226.27  226.61  226.18  226.2975 -28.7025
270     242.63  241.64  242.33  242.32  242.23   -27.77
285     259.89  258.83  258.92  259     259.16   -25.84
300     283.8   284.51  283.51  282.87  283.6725 -16.3275
315     294.05  295.47  295.23  295.57  295.08   -19.92
330     320.09  319.28  318.64  318.16  319.0425 -10.9575
345     342.39  342.87  342.34  343.13  342.6825 -2.3175
360     8.85    8.48    8.93    9.1     8.84     8.84
```

Graph of errors:

Is there some error I've made in the library, or might I be dealing with a faulty device?

(The dotted trendline is a 6th-order polynomial, to which I doubt indicates any actual relation. After all, I would expect this function to be cyclic.)

答:
Just a little late to the party ;p

In your getTiltHeading function, this line:

```<code>self.heading -= 2*math.pi
</code>```

might need to be:

```<code>self.tiltHeading -= 2*math.pi
</code>```

Body:
I recently acquired a Grove Sensor board for the LSM303D 6-Axis Accelerometer / Compass. Unfortunately, it transpired that the device did not yet have a Python library (only a C++ library and Arduino .ino file).

I am attempting to use it with the GrovePi+ board with Raspberry Pi, and would like to use it with Python code, so I made an attempt to transcribe the C++ Code into Python. However, I am getting odd output.

Additional information relating to the device can be found on the Pololu Datasheet

sudo i2cdetect -y 1 shows the device can be found at address 0x1E

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- 04 -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Here is the Python Code:

#!/usr/bin.env python

import smbus
import time
import math
import RPi.GPIO as GPIO
import struct

rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
    bus = smbus.SMBus(1)
else:
    bus = smbus.SMBus(0)

### LSM303 Address ###
LSM303D_ADDR    = 0x1E # Assuming SA0 grounded

### LSM303 Register definitions ###
TEMP_OUT_L      = 0x05
TEMP_OUT_H      = 0x06
STATUS_REG_M    = 0x07
OUT_X_L_M       = 0x08
OUT_X_H_M       = 0x09
OUT_Y_L_M       = 0x0A
OUT_Y_H_M       = 0x0B
OUT_Z_L_M       = 0x0C
OUT_Z_H_M       = 0x0D
WHO_AM_I        = 0x0F
INT_CTRL_M      = 0x12
INT_SRC_M       = 0x13
INT_THS_L_M     = 0x14
INT_THS_H_M     = 0x15
OFFSET_X_L_M    = 0x16
OFFSET_X_H_M    = 0x17
OFFSET_Y_L_M    = 0x18
OFFSET_Y_H_M    = 0x19
OFFSET_Z_L_M    = 0x1A
OFFSET_Z_H_M    = 0x1B
REFERENCE_X     = 0x1C
REFERENCE_Y     = 0x1D
REFERENCE_Z     = 0x1E
CTRL_REG0       = 0x1F
CTRL_REG1       = 0x20
CTRL_REG2       = 0x21
CTRL_REG3       = 0x22
CTRL_REG4       = 0x23
CTRL_REG5       = 0x24
CTRL_REG6       = 0x25
CTRL_REG7       = 0x26
STATUS_REG_A    = 0x27
OUT_X_L_A       = 0x28
OUT_X_H_A       = 0x29
OUT_Y_L_A       = 0x2A
OUT_Y_H_A       = 0x2B
OUT_Z_L_A       = 0x2C
OUT_Z_H_A       = 0x2D
FIFO_CTRL       = 0x2E
FIFO_SRC        = 0x2F
IG_CFG1         = 0x30
IG_SRC1         = 0x31
IG_THS1         = 0x32
IG_DUR1         = 0x33
IG_CFG2         = 0x34
IG_SRC2         = 0x35
IG_THS2         = 0x36
IG_DUR2         = 0x37
CLICK_CFG       = 0x38
CLICK_SRC       = 0x39
CLICK_THS       = 0x3A
TIME_LIMIT      = 0x3B
TIME_LATENCY    = 0x3C
TIME_WINDOW     = 0x3D
ACT_THS         = 0x3E
ACT_DUR         = 0x3F

### Mag scales ###
MAG_SCALE_2     = 0x00 # full-scale is +/- 2 Gauss
MAG_SCALE_4     = 0x20 # +/- 4 Guass
MAG_SCALE_8     = 0x40 # +/- 8 Guass
MAG_SCALE_12    = 0x60 # +/- 12 Guass

ACCEL_SCALE     = 2 # +/- 2g

X = 0
Y = 1
Z = 2

def twos_comp(val, bits):
    # Calculate the 2s complement of int:val #
    if(val&(1<<(bits-1)) != 0):
        val = val - (1<<bits)
    return val
#   return val if val < 32768 else val - 65536

class accelcomp:
    mag = [0,0,0]
    accel = [0,0,0]
    tiltcomp = [0,0,0]
    heading=0
    headingDegrees=0
    tiltHeading=0
    tiltHeadingDegrees=0

    def __init__(self):
        whoami = bus.read_byte_data(LSM303D_ADDR, WHO_AM_I)

        if(whoami == 0x49):
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG1, 0x57) # 0x57 = ODR=50hz, all accel axes on ## maybe 0x27 is Low Res?
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG2, (3<<6)|(0<<3)) # set full scale +/- 2g
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG3, 0x00) # no interrupt
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG4, 0x00) # no interrupt
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG5, (4<<2)) # 0x10 = mag 50Hz output rate
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG6, MAG_SCALE_2) # Magnetic Scale +/1 1.3 Guass
            bus.write_byte_data(LSM303D_ADDR, CTRL_REG7, 0x00) # 0x00 continuous conversion mode

    def getMag(self):
        self.mag[X] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_X_H_M) << 8 |
                          bus.read_byte_data(LSM303D_ADDR, OUT_X_L_M), 16)
        self.mag[Y] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_Y_H_M) << 8 |
                          bus.read_byte_data(LSM303D_ADDR, OUT_Y_L_M), 16)
        self.mag[Z] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_Z_H_M) << 8 |
                          bus.read_byte_data(LSM303D_ADDR, OUT_Z_L_M), 16)

    def getAccel(self):
        accel = [0,0,0]
        accel[X] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_X_H_A) << 8 |
                           bus.read_byte_data(LSM303D_ADDR, OUT_X_L_A), 16)
        accel[Y] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_Y_H_A) << 8 |
                           bus.read_byte_data(LSM303D_ADDR, OUT_Y_L_A), 16)
        accel[Z] = twos_comp(bus.read_byte_data(LSM303D_ADDR, OUT_Z_H_A) << 8 |
                           bus.read_byte_data(LSM303D_ADDR, OUT_Z_L_A), 16)

        for i in range(X, Z+1):
            self.accel[i] = accel[i] / math.pow(2, 15) * ACCEL_SCALE

    def getHeading(self):
        self.heading = math.atan2(self.mag[X], self.mag[Y])

        if self.heading < 0:
            self.heading += 2*math.pi
        if self.heading > 2*math.pi:
            self.heading -= 2*math.pi

        self.headingDegrees = round(math.degrees(self.heading),2)

    def getTiltHeading(self):
        truncate = [0,0,0]
        for i in range(X, Z+1):
            truncate[i] = math.copysign(min(math.fabs(self.accel[i]), 1.0), self.accel[i])
        try:
            pitch = math.asin(-1*truncate[X])
            roll = math.asin(truncate[Y]/math.cos(pitch)) if abs(math.cos(pitch)) >= abs(truncate[Y]) else 0
            # set roll to zero if pitch approaches -1 or 1

            self.tiltcomp[X] = self.mag[X] * math.cos(pitch) + self.mag[Z] * math.sin(pitch)
            self.tiltcomp[Y] = self.mag[X] * math.sin(roll) * math.sin(pitch) + \
                               self.mag[Y] * math.cos(roll) - self.mag[Z] * math.sin(roll) * math.cos(pitch)
            self.tiltcomp[Z] = self.mag[X] * math.cos(roll) * math.sin(pitch) + \
                               self.mag[Y] * math.sin(roll) + \
                               self.mag[Z] * math.cos(roll) * math.cos(pitch)
            self.tiltHeading = math.atan2(self.tiltcomp[Y], self.tiltcomp[X])

            if self.tiltHeading < 0:
                self.tiltHeading += 2*math.pi
            if self.tiltHeading > 2*math.pi:
                self.heading -= 2*math.pi

            self.tiltHeadingDegrees = round(math.degrees(self.tiltHeading),2)

        except Exception:
            print "AccelX {}, AccelY {}".format(self.accel[X], self.accel[Y])
            print "TruncX {}, TruncY {}".format(truncate[X], truncate[Y])
            print "Pitch {}, cos(pitch) {}, Bool(cos(pitch)) {}".format(pitch, math.cos(pitch), bool(math.cos(pitch)))

    def isMagReady(self):
        temp =  bus.read_byte_data(LSM303D_ADDR, STATUS_REG_M) & 0x03

        return temp

    def update(self):

        self.getAccel()
        self.getMag()
        self.getHeading()
        self.getTiltHeading()

if __name__ == '__main__':

    from time import sleep

    lsm = accelcomp()

    print '     Accelerometer     ||        Compass        ||              Heading'
    print '   x   |   y   |   z   ||   x   |   y   |   z   ||       calc      | tilt corrected  |'
    while True:
        lsm.getAccel()
        while not bool(lsm.isMagReady()):
            print "Not Ready!"
            sleep(.01)
        lsm.getMag()
        lsm.getHeading()
        lsm.getTiltHeading()
        print '{0:.3f} |{1:.3f} |{2:.3f} ||{3:6} |{4:6} |{5:6} ||  {6:6} deg     |  {7:6} deg     |'.format(
                    lsm.accel[X], lsm.accel[Y], lsm.accel[Z], lsm.mag[X], lsm.mag[Y], lsm.mag[Z], lsm.headingDegrees, lsm.tiltHeadingDegrees)
        sleep(.5)

Some sample output:

    Accelerometer     ||        Compass        ||              Heading
  x   |   y   |   z   ||   x   |   y   |   z   ||       calc      | tilt corrected  |
0.022 |-0.012 |1.056 ||   876 | -1119 |  5788 ||  141.94 deg     |  305.58 deg     |
0.027 |-0.011 |1.052 ||   919 | -1128 |  5826 ||  140.83 deg     |  305.62 deg     |
0.026 |-0.010 |1.053 ||   903 | -1108 |  5777 ||  140.82 deg     |  305.61 deg     |
0.024 |-0.009 |1.054 ||   914 | -1140 |  5790 ||  141.28 deg     |  305.57 deg     |
0.024 |-0.010 |1.056 ||   895 | -1122 |  5801 ||  141.42 deg     |  305.42 deg     |
0.024 |-0.010 |1.055 ||   905 | -1088 |  5747 ||  140.25 deg     |  306.69 deg     |
0.022 |-0.008 |1.057 ||   900 | -1106 |  5748 ||  140.86 deg     |  306.15 deg     |

One point that is obvious from the output displayed is that the acceleration in the Z direction is, sitting on the table, greater than 1g. It's close enough to be considered ok, although when tilted, both X and Y also go over 1g, which throws Math Errors with the asin function in getTiltHeading(), hence the truncation.

However, the real issue is with errors in the compass over a full rotation. I aligned the device north relative to the compass on my phone, and it gave a close value to 360 / 0 degrees. However, rotating it clockwise around the circle introduced errors that climbed up to about 30 degrees off the expected value around 255 degrees (near magnetic West).

Tabulated Experiment:

Angle   Trial 1 Trial 2 Trial 3 Trial 4 AVERAGE  ERROR
0       356.53  355.18  355.74  357.13  356.145  356.145
0       -3.47   -4.82   -4.26   -2.87   -3.855   -3.855
15      11.26   10.65   11.57   11.02   11.125   -3.875
30      30.29   30.82   30.74   30.29   30.535   0.535
45      40.24   40.32   39.95   39.93   40.11    -4.89
60      55.84   55.51   55.53   54.89   55.4425  -4.5575
75      67.23   67.42   68.46   68.23   67.835   -7.165
90      83.65   83.8    83.96   83.55   83.74    -6.26
105     101.11  100.91  100.13  100.66  100.7025 -4.2975
120     117.15  117.13  116.59  115.79  116.665  -3.335
135     125.92  125.56  125.19  126.14  125.702  -9.2975
150     142.74  142.44  142.94  142.56  142.67   -7.33
165     157.22  156.77  157.53  157.07  157.1475 -7.8525
180     171.97  171.61  172.17  172.26  172.0025 -7.9975
195     183.81  183.47  182.99  183.39  183.415  -11.585
210     195.59  196.6   197.2   197.58  196.7425 -13.2575
225     210.07  210.59  209.47  210.21  210.085  -14.915
240     218.97  219.3   219.53  219.48  219.32   -20.68
255     226.13  226.27  226.61  226.18  226.2975 -28.7025
270     242.63  241.64  242.33  242.32  242.23   -27.77
285     259.89  258.83  258.92  259     259.16   -25.84
300     283.8   284.51  283.51  282.87  283.6725 -16.3275
315     294.05  295.47  295.23  295.57  295.08   -19.92
330     320.09  319.28  318.64  318.16  319.0425 -10.9575
345     342.39  342.87  342.34  343.13  342.6825 -2.3175
360     8.85    8.48    8.93    9.1     8.84     8.84

Graph of errors:

Is there some error I've made in the library, or might I be dealing with a faulty device?

(The dotted trendline is a 6th-order polynomial, to which I doubt indicates any actual relation. After all, I would expect this function to be cyclic.)

Body:
Just a little late to the party ;p

In your getTiltHeading function, this line:

self.heading -= 2*math.pi

might need to be:

self.tiltHeading -= 2*math.pi


问:
How to design a simple proxy server that reads configuration files and blocks some websites?
Hi i was thinking to build simple proxy server for my flat so that our flatmates are not spending hours and hours downloading stuff, streaming on youtube and eating all the bandwidth. How am i going to build a simple proxy server so that i can restrict other flatmates going on some particular sites.
I was thinking to use some kind configurable file and list the name of the site that are going to be restricted.
the question is, where do i start form ? can anyone help me to generate an algorithm to build a simple server ?

Thanks

答: You would probably be better off using OpenDNS and having SQUID Proxy Server configured on the system from which you are sharing internet to other systems, rather than implementing your own solution as it is a very complex task to implement a proxy server which provides a decent level of security.</p>


问:
How do I replace part of a tree with another tree at the specified index in OCaml?
I have the following tree structure:

type 'a tree =
    | Function of string * 'a tree list  (* function name and arguments *)
    | Terminal of 'a
```
<p>I use this tree structure to construct an abstract syntax tree:</p>
<pre class="lang-ml prettyprint-override"><code>type atoms =
    | Int of int
    | Bool of bool

let t1 = Function ("+", [Function ("*", [Terminal (Int 5);
                                         Terminal (Int 6)]);
                         Function ("sqrt", [Terminal (Int 3)])])

let t2 = Function ("-", [Terminal (Int 4); Terminal (Int 2)])
</code>```

Tree representation of t1:

Tree representation of t2:

Goal: replace one of the subtrees in t1 with t2 at a specified t1 index position. The index position starts at 0 at the root node and is depth-first. In the figures above, I have labelled all the nodes with their index to show this.

For example, replace_subtree t1 4 t2 replaces the subtree at index 4 in t1 with t2, resulting in this tree:

Function ("+", [Function ("*", [Terminal (Int 5);
                                Terminal (Int 6)]);
                Function ("-", [Terminal (Int 4);
                                Terminal (Int 2)])])
```

This is essentially a crossover operation in tree-based genetic programming.

How do I implement replace_subtree in OCaml?

I would strongly prefer a purely functional solution.

Note that this question is similar to How do I replace part of a tree with another tree at the specified index?, except that the programming language in this question is OCaml instead of Scheme/Racket. I have some trouble understanding Scheme/Racket, so I am looking for an OCaml solution.

答:
Let's say you had a recursive function dfs that visited every node of a tree, with one parameter being the index number of the node.

Now rewrite this function to return an additional value which is a copy of the subtree below the node. I.e, it visits the subtrees of the node recursively (receiving copies of the subtrees) and constructs a new node as their parent.

Now add two parameters to the function, the index and the desired replacement. When reaching the desired index, the function returns the replacement instead of the copy of the node.

(Since this looks like possible homework I don't want to provide code.)

Body:
I have the following tree structure:

type 'a tree =
    | Function of string * 'a tree list  (* function name and arguments *)
    | Terminal of 'a

I use this tree structure to construct an abstract syntax tree:

type atoms =
    | Int of int
    | Bool of bool

let t1 = Function ("+", [Function ("*", [Terminal (Int 5);
                                         Terminal (Int 6)]);
                         Function ("sqrt", [Terminal (Int 3)])])

let t2 = Function ("-", [Terminal (Int 4); Terminal (Int 2)])

Tree representation of t1:

Tree representation of t2:

Goal: replace one of the subtrees in t1 with t2 at a specified t1 index position. The index position starts at 0 at the root node and is depth-first. In the figures above, I have labelled all the nodes with their index to show this.

For example, replace_subtree t1 4 t2 replaces the subtree at index 4 in t1 with t2, resulting in this tree:

Function ("+", [Function ("*", [Terminal (Int 5);
                                Terminal (Int 6)]);
                Function ("-", [Terminal (Int 4);
                                Terminal (Int 2)])])

This is essentially a crossover operation in tree-based genetic programming.

How do I implement replace_subtree in OCaml?

I would strongly prefer a purely functional solution.

Note that this question is similar to How do I replace part of a tree with another tree at the specified index?, except that the programming language in this question is OCaml instead of Scheme/Racket. I have some trouble understanding Scheme/Racket, so I am looking for an OCaml solution.