问:
Setting DEBUG = False causes 500 Error
Once I change the DEBUG = False, my site will generate 500 (using wsgi & manage.py runserver), and there is no error info in Apache error log and it will run normally when I change debug to True .

I'm using Django 1.5 & Python 2.7.3
here is Apache access log and without any log in apache error log

```<code>www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET / HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"
www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET /favicon.ico HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"
www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET /favicon.ico HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"
</code>```

Here is my settings file:

```<code>import os.path
DEBUG = False
#TEMPLATE_DEBUG = DEBUG

HERE = os.path.dirname(__file__)
ADMINS = (
    ('admin', 'xyzadmin@qq.com'),
)

MANAGERS = ADMINS

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'zdm',                      # Or path to database file if using sqlite3.
        'USER': 'root',                      # Not used with sqlite3.
        'PASSWORD': 'passwd',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Chicago'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = ''

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
#STATIC_ROOT = os.path.join(HERE, 'static').replace('\\','/')

# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
#STATIC_ROOT = os.path.join(HERE, 'static').replace('\\','/')
S= os.path.join(HERE, 'static').replace('\\','/')

# Additional locations of static files
STATICFILES_DIRS = (
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    '/home/zdm/static',
)

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

# Make this unique, and don't share it with anybody.
SECRET_KEY = '9a7!^gp8ojyk-^^d@*whuw!0rml+r+uaie4ur$(do9zz_6!hy0'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
#     'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'zdm.urls'

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'zdm.wsgi.application'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    '/home/zdm/templates',
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
    'zdm',
    'portal',
    'admin',
    'tagging',
)
</code>```

答: this maybe help someone else, in my case the problem with the missing favicon.</p>

Title: Setting DEBUG = False causes 500 Error

Body:
Once I change the DEBUG = False, my site will generate 500 (using wsgi & manage.py runserver), and there is no error info in Apache error log and it will run normally when I change debug to True .

I'm using Django 1.5 & Python 2.7.3
here is Apache access log and without any log in apache error log

www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET / HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"
www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET /favicon.ico HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"
www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET /favicon.ico HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"

Here is my settings file:

import os.path
DEBUG = False
#TEMPLATE_DEBUG = DEBUG

HERE = os.path.dirname(__file__)
ADMINS = (
    ('admin', 'xyzadmin@qq.com'),
)

MANAGERS = ADMINS

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'zdm',                      # Or path to database file if using sqlite3.
        'USER': 'root',                      # Not used with sqlite3.
        'PASSWORD': 'passwd',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Chicago'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = ''

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
#STATIC_ROOT = os.path.join(HERE, 'static').replace('\\','/')

# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
#STATIC_ROOT = os.path.join(HERE, 'static').replace('\\','/')
S= os.path.join(HERE, 'static').replace('\\','/')

# Additional locations of static files
STATICFILES_DIRS = (
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    '/home/zdm/static',
)

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

# Make this unique, and don't share it with anybody.
SECRET_KEY = '9a7!^gp8ojyk-^^d@*whuw!0rml+r+uaie4ur$(do9zz_6!hy0'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
#     'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'zdm.urls'

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'zdm.wsgi.application'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    '/home/zdm/templates',
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
    'zdm',
    'portal',
    'admin',
    'tagging',
)


来源: stackexchange

问:
finding astrology signs according to your month and date, simpler way to do it? instead of 12 if function
```<code>if month == 12:
    if 0 < date < 23:
        return 'SAG'
    if 23 <= date < 32:
        return 'CAP'
if month == 1:
    if 0 < date < 21:
        return 'CAP'
    if 21 <= date < 32:
        return 'AQU'
if month == 2:
    if 0 < date < 20:
        return 'AQU'
    if 20 <= date < 30:
        return 'PIS'
if month == 3:
    if 0 < date < 21:
            return 'PIS'
    if 21 <= date < 32:
            return 'ARI'
</code>```

<p>I am looking for a simpler and more effective way of completing my function of finding astrological sign according to month and date, is there a more effective method or is using 12 if loops a must?    </p>

答:
You're right to think there's a better way.  Use the datetime package.  Set up a list of start dates and check the appropriate range for the given date.  Since Capricorn spans the calendar year, you'll have two entries for that one:

```<code>import datetime
from datetime import date

signs = [ # start date, abbreviation
    (date(month=1, day=1), "CAP"),
    (date(month=1, day=20), "AQU"),
    (date(month=2, day=18), "PIC"),
    ...
    (date(month=12, day=19), "CAP"),
    (date(month=12, day=31), "end of year"),
]
</code>```

Now, you build a date from the given month and year.  Iterate through the list, looking for the a given date being greater than the current date, and less than the next one.  When you find that entry, you report/return the sign abbreviation.

Does that get you moving?

ContentLicense: CC BY-SA 4.0

Body:
if month == 12:
    if 0 < date < 23:
        return 'SAG'
    if 23 <= date < 32:
        return 'CAP'
if month == 1:
    if 0 < date < 21:
        return 'CAP'
    if 21 <= date < 32:
        return 'AQU'
if month == 2:
    if 0 < date < 20:
        return 'AQU'
    if 20 <= date < 30:
        return 'PIS'
if month == 3:
    if 0 < date < 21:
            return 'PIS'
    if 21 <= date < 32:
            return 'ARI'

I am looking for a simpler and more effective way of completing my function of finding astrological sign according to month and date, is there a more effective method or is using 12 if loops a must?

Body:
You're right to think there's a better way.  Use the datetime package.  Set up a list of start dates and check the appropriate range for the given date.  Since Capricorn spans the calendar year, you'll have two entries for that one:

import datetime
from datetime import date

signs = [ # start date, abbreviation
    (date(month=1, day=1), "CAP"),
    (date(month=1, day=20), "AQU"),
    (date(month=2, day=18), "PIC"),
    ...
    (date(month=12, day=19), "CAP"),
    (date(month=12, day=31), "end of year"),
]

Now, you build a date from the given month and year.  Iterate through the list, looking for the a given date being greater than the current date, and less than the next one.  When you find that entry, you report/return the sign abbreviation.

Does that get you moving?


问:
Can I install a library outside the library folder in Arduino?
I am working on an Arduino project with a friend and we need 2 external libraries, OneWire and DallasTemperature. I can easily install them on my computer and it will work completely fine, but I actually want to install them in my git folder, so anyone can instantly use my code. My folder structure is as follows:

```<code>project_folder/
> libraries/
  > OneWire/
    > OneWire.h and OneWire.cpp and so
  > DallasTemperature/
    > DallasTemperature.h and DallasTemperature.cpp and so
> project.ino
</code>```

In the header files I had to change some references, mostly file paths, so #include <OneWire.h> became #include "../OneWire/OneWire.h" and so and and I got no errors there. In my project.ino I loaded both libraries using #include "libraries/OneWire/OneWire.h" and #include "libraries/DallasTemperature/DallasTemperature.h", which all seem to work, but when I verify my code I get the following error:

```<code>C:\Users\<my username>\AppData\Local\Temp\ccZFsuFb.ltrans0.ltrans.o: In function `global constructors keyed to 65535_0_project.ino.cpp.o.1999':

<artificial>:(.text.startup+0x5e): undefined reference to `OneWire::begin(unsigned char)'

<artificial>:(.text.startup+0x6a): undefined reference to `DallasTemperature::DallasTemperature(OneWire*)'

C:\Users\<my username>\AppData\Local\Temp\ccZFsuFb.ltrans0.ltrans.o: In function `setup':

C:\Users\<my username>\Documents\<project folder>/project.ino:13: undefined reference to `DallasTemperature::begin()'

C:\Users\<my username>\AppData\Local\Temp\ccZFsuFb.ltrans0.ltrans.o: In function `loop':

C:\Users\<my username>\Documents\<project folder>/project.ino:17: undefined reference to `DallasTemperature::requestTemperatures()'

C:\Users\<my username>\Documents\<project folder>/project.ino:19: undefined reference to `DallasTemperature::getTempCByIndex(unsigned char)'

collect2.exe: error: ld returned 1 exit status

exit status 1
Error compiling for board Arduino Uno.
</code>```

Is there a possibility to install these libraries in my project folder or do I really have to install them seperately on each system?

答:
Is there a possibility to install these libraries in my project folder or do I really have to install them seperately on each system?

The answer is of course yes, First you need an IDE can make relative including

you can update your Arduino IDE for version >= 1.6.10 and restructure your folder to be as following

```<code>|project_folder/
|>src/
|   |> OneWire/
|   |   > OneWire.h and OneWire.cpp and so
|   |> DallasTemperature/
|   |   > DallasTemperature.h and DallasTemperature.cpp and so
|> project.ino
</code>```

and then include them from your sketch, like this

```<code>#include "src/OneWire/OneWire.h"
#include "src/DallasTemperature/DallasTemperature.h"
</code>```

Recommend option

use any other IDEs rather than Arduino IDE ... personally I prefer Atmel studio you can download atmel studio for free from the official site
and this lesson show how to convert Arduino sketches to work with atmel studio

Body:
I am working on an Arduino project with a friend and we need 2 external libraries, OneWire and DallasTemperature. I can easily install them on my computer and it will work completely fine, but I actually want to install them in my git folder, so anyone can instantly use my code. My folder structure is as follows:

project_folder/
> libraries/
  > OneWire/
    > OneWire.h and OneWire.cpp and so
  > DallasTemperature/
    > DallasTemperature.h and DallasTemperature.cpp and so
> project.ino

In the header files I had to change some references, mostly file paths, so #include <OneWire.h> became #include "../OneWire/OneWire.h" and so and and I got no errors there. In my project.ino I loaded both libraries using #include "libraries/OneWire/OneWire.h" and #include "libraries/DallasTemperature/DallasTemperature.h", which all seem to work, but when I verify my code I get the following error:

C:\Users\<my username>\AppData\Local\Temp\ccZFsuFb.ltrans0.ltrans.o: In function `global constructors keyed to 65535_0_project.ino.cpp.o.1999':

<artificial>:(.text.startup+0x5e): undefined reference to `OneWire::begin(unsigned char)'

<artificial>:(.text.startup+0x6a): undefined reference to `DallasTemperature::DallasTemperature(OneWire*)'

C:\Users\<my username>\AppData\Local\Temp\ccZFsuFb.ltrans0.ltrans.o: In function `setup':

C:\Users\<my username>\Documents\<project folder>/project.ino:13: undefined reference to `DallasTemperature::begin()'

C:\Users\<my username>\AppData\Local\Temp\ccZFsuFb.ltrans0.ltrans.o: In function `loop':

C:\Users\<my username>\Documents\<project folder>/project.ino:17: undefined reference to `DallasTemperature::requestTemperatures()'

C:\Users\<my username>\Documents\<project folder>/project.ino:19: undefined reference to `DallasTemperature::getTempCByIndex(unsigned char)'

collect2.exe: error: ld returned 1 exit status

exit status 1
Error compiling for board Arduino Uno.

Is there a possibility to install these libraries in my project folder or do I really have to install them seperately on each system?

Body:
Is there a possibility to install these libraries in my project folder or do I really have to install them seperately on each system?

The answer is of course yes, First you need an IDE can make relative including

you can update your Arduino IDE for version >= 1.6.10 and restructure your folder to be as following

|project_folder/
|>src/
|   |> OneWire/
|   |   > OneWire.h and OneWire.cpp and so
|   |> DallasTemperature/
|   |   > DallasTemperature.h and DallasTemperature.cpp and so
|> project.ino

and then include them from your sketch, like this

#include "src/OneWire/OneWire.h"
#include "src/DallasTemperature/DallasTemperature.h"

Recommend option

use any other IDEs rather than Arduino IDE ... personally I prefer Atmel studio you can download atmel studio for free from the official site
and this lesson show how to convert Arduino sketches to work with atmel studio


问:
Swift: Change value of another ViewController with delegation programmatically
I am trying to change the value of one ViewController by clicking a button inside a second ViewController with delegation.
But so far it only prints a message, but doesn't change the value.

I have this class where I defined a view:

```<code>class CounterView: UIView {

    public var creditPointValue = Int()

    let label = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.translatesAutoresizingMaskIntoConstraints = false
        backgroundColor = .cyan

        self.addSubview(label)
        label.text = "Credit Points: \(creditPointValue)"
        label.translatesAutoresizingMaskIntoConstraints = false;
        label.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true

    }

    func changeCreditPointValue(value:Int){
        creditPointValue = creditPointValue + value
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
</code>```

I am using that view inside this ViewController and I want to manipulate the variable "creditPointValue":

```<code>protocol AddCreditsDelegate {
    func addCreditsToCounter()
}

class ViewController: UIViewController {

    var delegate: AddCreditsDelegate?

    var counterView = CounterView()

    let label = UILabel()

    let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        view.backgroundColor = .white

        view.addSubview(button)
        button.backgroundColor = .red
        button.setTitle("View2", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(changeView), for: .touchUpInside)
        button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

    override func viewDidAppear(_ animated: Bool) {
        view.addSubview(counterView)
        counterView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        counterView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        counterView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        //counterView.frame.size.height = 30
        counterView.bottomAnchor.constraint(equalTo: counterView.topAnchor, constant: 50).isActive = true

    }

    @objc func changeView(){
        delegate?.addCreditsToCounter()
        navigationController?.pushViewController(ViewController2(), animated: true)
    }
}
</code>```

And inside this second ViewController I am trying to change the value by clicking the button I added to the view:

```<code>class ViewController2: UIViewController {

    let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        view.addSubview(button)
               button.backgroundColor = .red
               button.setTitle("add Credits", for: .normal)
               button.translatesAutoresizingMaskIntoConstraints = false
               button.addTarget(self, action: #selector(addCreditsButton), for: .touchUpInside)
               button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
               button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

    @objc func addCreditsButton(){
        addCreditsToCounter()
    }
}

extension ViewController2 : AddCreditsDelegate{
    func addCreditsToCounter() {
        let vc = ViewController()
        vc.delegate = self
        vc.counterView.creditPointValue += 5
        print("pressed")
    }
}
</code>```

So far only the message "pressed" gets printed each time I click the button and I don't even know if I am going into the right direction with my approach trying to use delegation.

答:
You should not create a new ViewController instance each time you call ViewController2.addCreditsToCounter, you already have a ViewController that creates a ViewController2 instance in ViewController.changeView. Just store a weak reference to ViewController in ViewController2 using delegate. In such case ViewController (not ViewController2) should conform to AddCreditsDelegate.
First of all, replace

```<code>protocol AddCreditsDelegate {
    func addCreditsToCounter()
}
</code>```

with

```<code>protocol AddCreditsDelegate: AnyObject {
    func addCreditsToCounter()
}
</code>```

Then add weak var delegate: AddCreditsDelegate? to ViewController2 and remove ViewController.delegate. Remove ViewController2.addCreditsToCounter, ViewController2 should not conform to AddCreditsDelegate. It means that in ViewController2.addCreditsButton you should call delegate?.addCreditsToCounter(), not addCreditsToCounter().

ViewController should conform to AddCreditsDelegate:

```<code>extension ViewController: AddCreditsDelegate {
    func addCreditsToCounter() {
        counterView.creditPointValue += 5
        print("pressed")
    }
}
</code>```

And don't forget to initialize ViewController2.delegate. Replace your ViewController.changeView implementation with

```<code>let controller = ViewController2()
controller.delegate = self
navigationController?.pushViewController(controller, animated: true)
</code>```

Body:
I am trying to change the value of one ViewController by clicking a button inside a second ViewController with delegation.
But so far it only prints a message, but doesn't change the value.

I have this class where I defined a view:

class CounterView: UIView {

    public var creditPointValue = Int()

    let label = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.translatesAutoresizingMaskIntoConstraints = false
        backgroundColor = .cyan

        self.addSubview(label)
        label.text = "Credit Points: \(creditPointValue)"
        label.translatesAutoresizingMaskIntoConstraints = false;
        label.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true

    }

    func changeCreditPointValue(value:Int){
        creditPointValue = creditPointValue + value
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

I am using that view inside this ViewController and I want to manipulate the variable "creditPointValue":

protocol AddCreditsDelegate {
    func addCreditsToCounter()
}

class ViewController: UIViewController {

    var delegate: AddCreditsDelegate?

    var counterView = CounterView()

    let label = UILabel()

    let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        view.backgroundColor = .white

        view.addSubview(button)
        button.backgroundColor = .red
        button.setTitle("View2", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(changeView), for: .touchUpInside)
        button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

    override func viewDidAppear(_ animated: Bool) {
        view.addSubview(counterView)
        counterView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        counterView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        counterView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        //counterView.frame.size.height = 30
        counterView.bottomAnchor.constraint(equalTo: counterView.topAnchor, constant: 50).isActive = true

    }

    @objc func changeView(){
        delegate?.addCreditsToCounter()
        navigationController?.pushViewController(ViewController2(), animated: true)
    }
}

And inside this second ViewController I am trying to change the value by clicking the button I added to the view:

class ViewController2: UIViewController {

    let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        view.addSubview(button)
               button.backgroundColor = .red
               button.setTitle("add Credits", for: .normal)
               button.translatesAutoresizingMaskIntoConstraints = false
               button.addTarget(self, action: #selector(addCreditsButton), for: .touchUpInside)
               button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
               button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

    @objc func addCreditsButton(){
        addCreditsToCounter()
    }
}

extension ViewController2 : AddCreditsDelegate{
    func addCreditsToCounter() {
        let vc = ViewController()
        vc.delegate = self
        vc.counterView.creditPointValue += 5
        print("pressed")
    }
}

So far only the message "pressed" gets printed each time I click the button and I don't even know if I am going into the right direction with my approach trying to use delegation.

Body:
You should not create a new ViewController instance each time you call ViewController2.addCreditsToCounter, you already have a ViewController that creates a ViewController2 instance in ViewController.changeView. Just store a weak reference to ViewController in ViewController2 using delegate. In such case ViewController (not ViewController2) should conform to AddCreditsDelegate.
First of all, replace

protocol AddCreditsDelegate {
    func addCreditsToCounter()
}

with

protocol AddCreditsDelegate: AnyObject {
    func addCreditsToCounter()
}

Then add weak var delegate: AddCreditsDelegate? to ViewController2 and remove ViewController.delegate. Remove ViewController2.addCreditsToCounter, ViewController2 should not conform to AddCreditsDelegate. It means that in ViewController2.addCreditsButton you should call delegate?.addCreditsToCounter(), not addCreditsToCounter().

ViewController should conform to AddCreditsDelegate:

extension ViewController: AddCreditsDelegate {
    func addCreditsToCounter() {
        counterView.creditPointValue += 5
        print("pressed")
    }
}

And don't forget to initialize ViewController2.delegate. Replace your ViewController.changeView implementation with

let controller = ViewController2()
controller.delegate = self
navigationController?.pushViewController(controller, animated: true)


问:
Sort a list by presence of items in another list
Suppose I have two lists:

```<code>a = ['30', '10', '90', '1111', '17']
b = ['60', '1201', '30', '17', '900']
</code>```

How would you sort this most efficiently, such that:

list b is sorted with respect to a. Unique elements in b should be placed at the end of the sorted list. Unique elements in a can be ignored.

example output:

```<code>c = ['30', '17', '60', '1201', '900']
</code>```

Sorry, it's a simple question. My attempt is stuck at the point of taking the intersection.

```<code>intersection = sorted(set(a) & set(b), key = a.index)
</code>```

Body:
Suppose I have two lists:

a = ['30', '10', '90', '1111', '17']
b = ['60', '1201', '30', '17', '900']

How would you sort this most efficiently, such that:

list b is sorted with respect to a. Unique elements in b should be placed at the end of the sorted list. Unique elements in a can be ignored.

example output:

c = ['30', '17', '60', '1201', '900']

Sorry, it's a simple question. My attempt is stuck at the point of taking the intersection.

intersection = sorted(set(a) & set(b), key = a.index)

Body:
Your title is actually clearer than your description and can be pretty directly translated to code:

Sort a list by presence of items in another list

Code:

>>> sorted(b, key=set(a).__contains__, reverse=True)
['30', '17', '60', '1201', '900']

or

>>> sorted(b, key=lambda x, s=set(a): x not in s)
['30', '17', '60', '1201', '900']

Sorting booleans is practically indistinguishable from linear time, and these solutions are faster than the accepted solution both on your example data as well as on example data I tried with millions of random numbers (where about half of b's elements were in a).

Benchmarks

   n    b in a   kaya1    kaya2    heap1    heap2    heap3
----------------------------------------------------------
   1024 53.12%  0.00046  0.00033  0.00020  0.00067  0.00018
   2048 51.03%  0.00142  0.00069  0.00048  0.00071  0.00060
   4096 50.34%  0.00226  0.00232  0.00127  0.00183  0.00125
   8192 50.42%  0.00938  0.00843  0.00328  0.00471  0.00351
  16384 50.38%  0.02010  0.01647  0.00776  0.00992  0.00839
  32768 49.96%  0.03987  0.03165  0.01661  0.02326  0.01951
  65536 50.20%  0.08002  0.06548  0.03326  0.04828  0.03896
 131072 50.04%  0.16118  0.12863  0.06671  0.09642  0.07840
 262144 50.06%  0.32698  0.26757  0.13477  0.19342  0.15828
 524288 50.08%  0.66735  0.54627  0.27378  0.38365  0.32496
1048576 50.00%  1.34095  1.08972  0.54703  0.78028  0.65623
2097152 50.03%  2.68957  2.20556  1.13797  1.60649  1.33975
4194304 50.01%  5.36141  4.33496  2.25494  3.18520  2.70506
8388608 49.99% 10.72588  8.74114  4.56061  6.35421  5.36515

Note:

n is the size of b.

a is prepared as a set before benchmarking the functions, in order to focus on their differences. The size of a is always 8388608 in order to keep in a checks constant time (even sets get slower when they get larger).

b in a is the percentage of elements of b in a. I made them so that this is about 50%.

kaya1 and kaya2 are from the accepted answer by @kaya3, modified so that they do what I think is the task (sort b by presence of items in a, not "a & b" followed by "b \ a").

heap1 and heap2 are my above two solutions using sorted.

heap3 is the fastest solution without sorted that I was able to write.

The results are times in seconds.

Benchmark code:

from timeit import repeat
import random

def kaya1(a_set, b):
    return [*filter(lambda x: x in a_set, b), *filter(lambda x: x not in a_set, b)]

def kaya2(a_set, b):
    return [*(x for x in b if x in a_set), *(x for x in b if x not in a_set)]

def heap1(a_set, b):
    return sorted(b, key=a_set.__contains__, reverse=True)

def heap2(a_set, b):
    return sorted(b, key=lambda x: x not in a_set)

def heap3(a_set, b):
    not_in_a = []
    append = not_in_a.append
    in_a = [x for x in b if x in a_set or append(x)]
    in_a.extend(not_in_a)
    return in_a

print('   n    b in a   kaya1    kaya2    heap1    heap2    heap3')
print('----------------------------------------------------------')

A = random.sample(range(2**24), 2**23)
B = random.sample(range(2**24), 2**23)
a_set = set(A)

for e in range(10, 24):
    n = 2**e
    b = B[:n]
    print('%7d %5.2f%%' % (n, 100 * len(set(b) & a_set) / len(b)), end='')
    expect = None
    for sort in kaya1, kaya2, heap1, heap2, heap3:
        t = min(repeat(lambda: sort(a_set, b), number=1))
        print('%9.5f' % t, end='')
        output = sort(a_set, b)
        if expect is None:
            expect = output
        else:
            assert output == expect
    print()


问:
Removing unused strings during ProGuard optimisation
I include this ProGuard configuration to strip out debug log statements when I release an Android application:

```<code>-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}
</code>```

This works as expected — I can see from the ProGuard logs and Android log output that calls such as Log.d("This is a debug statement"); are removed.

However, if I decompile the app at this stage, I can still see all the String literals that were used — i.e. This is a debug statement in this example.

Is there a way to also remove each String that's no longer needed from the bytecode?

答:
ProGuard can remove simple constant arguments (Strings, integers, etc). So in this case, the code and the string constant should disappear completely:

```<code>Log.d("This is a debug statement");
</code>```

However, you may have observed the issue with some code like this:

```<code>Log.d("The answer is "+answer);
</code>```

After compilation, this actually corresponds to:

```<code>Log.d(new StringBuilder().append("The answer is ").append(answer).toString());
</code>```

ProGuard version 4.6 can simplify this to something like:

```<code>new StringBuilder().append("The answer is ").append(answer).toString();
</code>```

So the logging is gone, but the optimization step still leaves some fluff behind. It's surprisingly tricky to simplify this without some deeper knowledge about the StringBuilder class. As far as ProGuard is concerned, it could say:

```<code>new DatabaseBuilder().setup("MyDatabase").initialize(table).close();
</code>```

For a human, the StringBuilder code can obviously be removed, but the DatabaseBuilder code probably can't. ProGuard requires escape analysis and a few other techniques, which aren't in this version yet.

As for a solution: you can create additional debug methods that take simple arguments, and let ProGuard remove those:

```<code>MyLog.d("The answer is ", answer);
</code>```

Alternatively, you can try prefixing every debug statement with a condition that ProGuard can later evaluate as false. This option may be a bit more convoluted, requiring some additional -assumenosideeffects option on an initialization method for the debug flag.

ContentLicense: CC BY-SA 3.0

Body:
I include this ProGuard configuration to strip out debug log statements when I release an Android application:

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}

This works as expected — I can see from the ProGuard logs and Android log output that calls such as Log.d("This is a debug statement"); are removed.

However, if I decompile the app at this stage, I can still see all the String literals that were used — i.e. This is a debug statement in this example.

Is there a way to also remove each String that's no longer needed from the bytecode?

Body:
ProGuard can remove simple constant arguments (Strings, integers, etc). So in this case, the code and the string constant should disappear completely:

Log.d("This is a debug statement");

However, you may have observed the issue with some code like this:

Log.d("The answer is "+answer);

After compilation, this actually corresponds to:

Log.d(new StringBuilder().append("The answer is ").append(answer).toString());

ProGuard version 4.6 can simplify this to something like:

new StringBuilder().append("The answer is ").append(answer).toString();

So the logging is gone, but the optimization step still leaves some fluff behind. It's surprisingly tricky to simplify this without some deeper knowledge about the StringBuilder class. As far as ProGuard is concerned, it could say:

new DatabaseBuilder().setup("MyDatabase").initialize(table).close();

For a human, the StringBuilder code can obviously be removed, but the DatabaseBuilder code probably can't. ProGuard requires escape analysis and a few other techniques, which aren't in this version yet.

As for a solution: you can create additional debug methods that take simple arguments, and let ProGuard remove those:

MyLog.d("The answer is ", answer);

Alternatively, you can try prefixing every debug statement with a condition that ProGuard can later evaluate as false. This option may be a bit more convoluted, requiring some additional -assumenosideeffects option on an initialization method for the debug flag.


问:
How to serve multiple gcloud service with one domain
I have multiple gcloud services running for different tasks. Some use functions, some app-engine and one is a compute engine machine.
How can I serve all of theme with one public domain?

I imagine some kind of mapping or routing like :

```<code>example.de/auth => function A
example.de/wallet => app-engine default service
example.de/user => cloud run service
...
</code>```

I've red that cloud endpoints is the pendant to aws AWS api-gateway.
But as far as I understand I cannot apply a domain to cloud endpoints in general.

What can I use to build such kind of facade (example.de domain)?

答:
Google Cloud Endpoints are a service that can be run in a docker image, GKE, or Cloud Run.

If you are running Cloud Endpoinsts as a service in Cloudrun then you can configure the custom domain for the the cloud Run service following This Guide which how to add a mapping to a custom domain.

Body:
I have multiple gcloud services running for different tasks. Some use functions, some app-engine and one is a compute engine machine.
How can I serve all of theme with one public domain?

I imagine some kind of mapping or routing like :

example.de/auth => function A
example.de/wallet => app-engine default service
example.de/user => cloud run service
...

I've red that cloud endpoints is the pendant to aws AWS api-gateway.
But as far as I understand I cannot apply a domain to cloud endpoints in general.

What can I use to build such kind of facade (example.de domain)?


问:
Firebase NullPointerException immediately after creating/signing in the user
I am trying to allow new users to upload profile pictures but whenever I attempt to register, the app crashes. After debugging the app I found that it always occurs due to line 175 having an empty user ID. Line 175 is: DatabaseReference myRef = firebaseDatabase.getReference(firebaseAuth.getUid());

I have been following this YouTube tutorial ,https://www.youtube.com/watch?v=-v1O9rxienU, and he uploads images with no problems even though we have the same code. How do I fix this?

Here is the error text from the debug console:

```<code>E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.fbla_mobileapp, PID: 31103
    java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.storage.StorageReference com.google.firebase.storage.StorageReference.child(java.lang.String)' on a null object reference
        at com.example.fbla_mobileapp.Register_Form.sendUserData(Register_Form.java:176)
        at com.example.fbla_mobileapp.Register_Form.access$400(Register_Form.java:41)
        at com.example.fbla_mobileapp.Register_Form$2$1.onComplete(Register_Form.java:116)
        at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:205)
        at android.app.ActivityThread.main(ActivityThread.java:6991)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:884)
</code>```

And the code:

```<code>    private EditText userName, userPassword, userEmail, userGrade;
private Button regButton;
private TextView userLogin;
private FirebaseAuth firebaseAuth;
private ImageView userProfilePic;
String email, name, grade, password;
private FirebaseStorage firebaseStorage;
private static int PICK_IMAGE = 123;
Uri imagePath;
private StorageReference storageReference;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == PICK_IMAGE && resultCode == RESULT_OK && data.getData() != null){
        imagePath = data.getData();
        try {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imagePath);
            userProfilePic.setImageBitmap(bitmap);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_register__form);
    setupUiViews();

    firebaseAuth = FirebaseAuth.getInstance();
    firebaseStorage = FirebaseStorage.getInstance();

    final StorageReference storageReference = firebaseStorage.getReference();

    userProfilePic.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //  Intent galleryIntent = new Intent();
            //  galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
            // galleryIntent.setType("image/*");
            // startActivityForResult(galleryIntent, Gallery_Pick);
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent, "Select Image"), PICK_IMAGE);

        }
    });

    regButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(validate()){
                //upload to database
                //StorageReference myRef1 = storageReference.child(firebaseAuth.getUid());
                String user_email = userEmail.getText().toString().trim();
                String user_password = userPassword.getText().toString().trim();

                firebaseAuth.createUserWithEmailAndPassword(user_email, user_password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {

                            if (task.isSuccessful()) {
                                sendUserData(task.getResult().getUser());
                            firebaseAuth.signOut();
                            Toast.makeText(Register_Form.this, "Registration Successful", Toast.LENGTH_SHORT).show();
                            startActivity(new Intent(Register_Form.this, login_screen.class));
                        }else{
                            Toast.makeText(Register_Form.this, "Registration Failed", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            }

        }
    });

    userLogin.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(Register_Form.this, login_screen.class ));
        }
    });

    }

private void setupUiViews(){
    userName = (EditText)findViewById(R.id.etName);
    userEmail = (EditText)findViewById(R.id.etEmail);
    userPassword = (EditText)findViewById(R.id.etPass);
    regButton = (Button)findViewById(R.id.btnRegister);
   // regButton.setOnClickListener();
    userLogin = (TextView)findViewById(R.id.tvSIgn_In);
    userGrade = (EditText)findViewById(R.id.etGrade);
    userProfilePic =(ImageView)findViewById(R.id.ivProfile);

}

private Boolean validate(){

    Boolean result = false;

     name = userName.getText().toString();
     password = userPassword.getText().toString();
     email = userEmail.getText().toString();
     grade = userGrade.getText().toString();

    if(name.isEmpty() || password.isEmpty() || email.isEmpty() || grade.isEmpty() || imagePath == null ) {
        Toast.makeText(this, "Please enter all details", Toast.LENGTH_SHORT).show();
    }else{
        result = true;
    }
    return result;
}

private void sendUserData(FirebaseUser user){

    FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
    DatabaseReference myRef = firebaseDatabase.getReference(firebaseAuth.getUid());
   StorageReference imageReference = storageReference.child(firebaseAuth.getUid()).child("Images").child("Profile Pic");  //User id/Images/Profile Pic.jpg
   UploadTask uploadTask = imageReference.putFile(imagePath);
   uploadTask.addOnFailureListener(new OnFailureListener() {
       @Override
       public void onFailure(@NonNull Exception e) {
           Toast.makeText(Register_Form.this, "Upload failed!", Toast.LENGTH_SHORT).show();
       }
   }).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
            Toast.makeText(Register_Form.this, "Upload successful!", Toast.LENGTH_SHORT).show();
     }
    });
    UserProfile userProfile = new UserProfile(grade, email, name);
    myRef.setValue(userProfile);
}
</code>```

}

答:
After creating/signing in the user, the FirebaseAuth.getInstance().getCurrentUser() may not immediately be updated. To prevent a race condition, you'll want to pass the user from the AuthResult into sendUserData.

```<code>firebaseAuth.createUserWithEmailAndPassword(user_email, user_password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
    @Override
    public void onComplete(@NonNull Task<AuthResult> task) {

        if (task.isSuccessful()) {
            sendUserData(task.getResult().getUser());
            ...
</code>```

Then in your sendUserData, you get the UID from that user, instead of the global object:

```<code>private void sendUserData(FirebaseUser user){
    String uid = user.getUid();
    FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
    DatabaseReference myRef = firebaseDatabase.getReference(uid);
    StorageReference imageReference = storageReference.child(uid).child("Images").child("Profile Pic");
</code>```

Body:
I am trying to allow new users to upload profile pictures but whenever I attempt to register, the app crashes. After debugging the app I found that it always occurs due to line 175 having an empty user ID. Line 175 is: DatabaseReference myRef = firebaseDatabase.getReference(firebaseAuth.getUid());

I have been following this YouTube tutorial ,https://www.youtube.com/watch?v=-v1O9rxienU, and he uploads images with no problems even though we have the same code. How do I fix this?

Here is the error text from the debug console:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.fbla_mobileapp, PID: 31103
    java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.storage.StorageReference com.google.firebase.storage.StorageReference.child(java.lang.String)' on a null object reference
        at com.example.fbla_mobileapp.Register_Form.sendUserData(Register_Form.java:176)
        at com.example.fbla_mobileapp.Register_Form.access$400(Register_Form.java:41)
        at com.example.fbla_mobileapp.Register_Form$2$1.onComplete(Register_Form.java:116)
        at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:205)
        at android.app.ActivityThread.main(ActivityThread.java:6991)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:884)

And the code:

    private EditText userName, userPassword, userEmail, userGrade;
private Button regButton;
private TextView userLogin;
private FirebaseAuth firebaseAuth;
private ImageView userProfilePic;
String email, name, grade, password;
private FirebaseStorage firebaseStorage;
private static int PICK_IMAGE = 123;
Uri imagePath;
private StorageReference storageReference;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == PICK_IMAGE && resultCode == RESULT_OK && data.getData() != null){
        imagePath = data.getData();
        try {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imagePath);
            userProfilePic.setImageBitmap(bitmap);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_register__form);
    setupUiViews();

    firebaseAuth = FirebaseAuth.getInstance();
    firebaseStorage = FirebaseStorage.getInstance();

    final StorageReference storageReference = firebaseStorage.getReference();

    userProfilePic.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //  Intent galleryIntent = new Intent();
            //  galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
            // galleryIntent.setType("image/*");
            // startActivityForResult(galleryIntent, Gallery_Pick);
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent, "Select Image"), PICK_IMAGE);

        }
    });

    regButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(validate()){
                //upload to database
                //StorageReference myRef1 = storageReference.child(firebaseAuth.getUid());
                String user_email = userEmail.getText().toString().trim();
                String user_password = userPassword.getText().toString().trim();

                firebaseAuth.createUserWithEmailAndPassword(user_email, user_password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {

                            if (task.isSuccessful()) {
                                sendUserData(task.getResult().getUser());
                            firebaseAuth.signOut();
                            Toast.makeText(Register_Form.this, "Registration Successful", Toast.LENGTH_SHORT).show();
                            startActivity(new Intent(Register_Form.this, login_screen.class));
                        }else{
                            Toast.makeText(Register_Form.this, "Registration Failed", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            }

        }
    });

    userLogin.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(Register_Form.this, login_screen.class ));
        }
    });

    }

private void setupUiViews(){
    userName = (EditText)findViewById(R.id.etName);
    userEmail = (EditText)findViewById(R.id.etEmail);
    userPassword = (EditText)findViewById(R.id.etPass);
    regButton = (Button)findViewById(R.id.btnRegister);
   // regButton.setOnClickListener();
    userLogin = (TextView)findViewById(R.id.tvSIgn_In);
    userGrade = (EditText)findViewById(R.id.etGrade);
    userProfilePic =(ImageView)findViewById(R.id.ivProfile);

}

private Boolean validate(){

    Boolean result = false;

     name = userName.getText().toString();
     password = userPassword.getText().toString();
     email = userEmail.getText().toString();
     grade = userGrade.getText().toString();

    if(name.isEmpty() || password.isEmpty() || email.isEmpty() || grade.isEmpty() || imagePath == null ) {
        Toast.makeText(this, "Please enter all details", Toast.LENGTH_SHORT).show();
    }else{
        result = true;
    }
    return result;
}

private void sendUserData(FirebaseUser user){

    FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
    DatabaseReference myRef = firebaseDatabase.getReference(firebaseAuth.getUid());
   StorageReference imageReference = storageReference.child(firebaseAuth.getUid()).child("Images").child("Profile Pic");  //User id/Images/Profile Pic.jpg
   UploadTask uploadTask = imageReference.putFile(imagePath);
   uploadTask.addOnFailureListener(new OnFailureListener() {
       @Override
       public void onFailure(@NonNull Exception e) {
           Toast.makeText(Register_Form.this, "Upload failed!", Toast.LENGTH_SHORT).show();
       }
   }).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
            Toast.makeText(Register_Form.this, "Upload successful!", Toast.LENGTH_SHORT).show();
     }
    });
    UserProfile userProfile = new UserProfile(grade, email, name);
    myRef.setValue(userProfile);
}

}

Body:
After creating/signing in the user, the FirebaseAuth.getInstance().getCurrentUser() may not immediately be updated. To prevent a race condition, you'll want to pass the user from the AuthResult into sendUserData.

firebaseAuth.createUserWithEmailAndPassword(user_email, user_password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
    @Override
    public void onComplete(@NonNull Task<AuthResult> task) {

        if (task.isSuccessful()) {
            sendUserData(task.getResult().getUser());
            ...

Then in your sendUserData, you get the UID from that user, instead of the global object:

private void sendUserData(FirebaseUser user){
    String uid = user.getUid();
    FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
    DatabaseReference myRef = firebaseDatabase.getReference(uid);
    StorageReference imageReference = storageReference.child(uid).child("Images").child("Profile Pic");


问:
Create a string list into a float list
I was reading from a file and was able to compute a list, but sadly it reads as :
['40\n', '35\n', '49\n', '53\n', '38\n', '39\n', '40\n', '37\n', '49\n', '34\n', '38\n', '43\n', '47\n', '\n']
when I would like it to read as:
['40', '35', '49', '53', '38', '39', '40', '37', '49', '34', '38', '43', '47']
I know I have to append it and/or slice it in order to turn in into floats. I am really stuck on this part. This is the one part that will make the rest of my code work. Any help is appreciated!

Title: Create a string list into a float list

Body:
a = ['40\n', '35\n', '49\n', '53\n', '38\n', '39\n', '40\n', '37\n', '49\n', '34\n', '38\n', '43\n', '47\n', '\n']

float_a = [float(x[:-1]) for x in a if x != '\n']

You can easily convert this list with a list comprehension to a list of floats.


问:
Split whitespaces and search user input
I have an input field where users can search a database for a certain name. The database contains names such as "Doe, John".

If a user searches for "john" I think it's easy to implement. However, if he or she searches for "john Doe" I would like to implement the logic search for john or search for doe.

With RegEx I am completely lost. Is something like this even possible? However, with JS I would at least be able to consider this algorithm:

Split the input on a whitespace and create to arrays

Remove special characters

Filter the JSON object retrieved from the database

check, whether item includes the cleansed string-arrays

As for the JS-functions I tried something (in vain):

```<code>        let search = 'John Doe' //user input
        let data = ['Doe, John', 'Bean, Mister'] //data from database
        let split = search.split(" ") //split the whitespace into two arrays
        split = split.map(item => { return item.replace(/[^\w\s]+/gi, '')}) //remove dots, commas etc.
        let result = data.filter(item => { //filter each item from the data...
            split.forEach(element => {
            let found = item.match(new RegExp(element, "i")) // so here I get matches, but how can I move them up the let the filter method return true?
            return found.length
            }).length>0

        })
        console.log(result)
</code>```

Thanks to Taplars comment, I have used a map-method instead of a forEach:

```<code>let data = ['Doe, John', 'Bean, Mister']
    let split = search.split(" ")
    split = split.map(item => { return item.replace(/[^\w\s]+/gi, '')})
    let result = data.filter(item => {
      let filtered =   split.map(element => {
            let ret = item.match(new RegExp(element, "i"))
            return ret
        })
      console.log(item,filtered) //now I have two arrays, one with something meaningful and one with [null,null]. How can I remove empty arrays?
      return filtered.length>0
    })
    console.log(result)
</code>```

答:
If you want to make it non-greedy (every user word is optional)

const data = ['Doe, John', 'Bean, Mister', 'Mardoe, Ann']; // data
const search = '  joh  doe  '; // user input

// Remove spaces and create Piped | options
const searchPipe = search.trim().replace(/[|\s]+/g, '|');
const result = data.filter(item => new RegExp(searchPipe, 'i').test(item));

console.log(result)```
</div>
</div>
</p>

<p>To make it greedy (<strong>must contain every word</strong>)</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const data = ['Doe, John', 'Bean, Mister', 'Mardoe, Ann']; // data
const search = '  joh  doe  '; // user input

// Remove extra spaces and create array
const searchArr = search.trim().replace(/\s+/g, ' ').split(' ');
const result = data.filter(item => searchArr.every(sa => new RegExp(sa, 'i').test(item)));

console.log(result)</code>```

Notice, if a person named "Doe, Doe" was in the list, the above would account it (since the length) for a "john doe" search, but I think it's fine.

Title: Split whitespaces and search user input

Body:
I have an input field where users can search a database for a certain name. The database contains names such as "Doe, John".

If a user searches for "john" I think it's easy to implement. However, if he or she searches for "john Doe" I would like to implement the logic search for john or search for doe.

With RegEx I am completely lost. Is something like this even possible? However, with JS I would at least be able to consider this algorithm:

Split the input on a whitespace and create to arrays

Remove special characters

Filter the JSON object retrieved from the database

check, whether item includes the cleansed string-arrays

As for the JS-functions I tried something (in vain):

        let search = 'John Doe' //user input
        let data = ['Doe, John', 'Bean, Mister'] //data from database
        let split = search.split(" ") //split the whitespace into two arrays
        split = split.map(item => { return item.replace(/[^\w\s]+/gi, '')}) //remove dots, commas etc.
        let result = data.filter(item => { //filter each item from the data...
            split.forEach(element => {
            let found = item.match(new RegExp(element, "i")) // so here I get matches, but how can I move them up the let the filter method return true?
            return found.length
            }).length>0

        })
        console.log(result)

Thanks to Taplars comment, I have used a map-method instead of a forEach:

let data = ['Doe, John', 'Bean, Mister']
    let split = search.split(" ")
    split = split.map(item => { return item.replace(/[^\w\s]+/gi, '')})
    let result = data.filter(item => {
      let filtered =   split.map(element => {
            let ret = item.match(new RegExp(element, "i"))
            return ret
        })
      console.log(item,filtered) //now I have two arrays, one with something meaningful and one with [null,null]. How can I remove empty arrays?
      return filtered.length>0
    })
    console.log(result)

Body:
If you want to make it non-greedy (every user word is optional)

const data = ['Doe, John', 'Bean, Mister', 'Mardoe, Ann']; // data
const search = '  joh  doe  '; // user input

// Remove spaces and create Piped | options
const searchPipe = search.trim().replace(/[|\s]+/g, '|');
const result = data.filter(item => new RegExp(searchPipe, 'i').test(item));

console.log(result)

To make it greedy (must contain every word)

const data = ['Doe, John', 'Bean, Mister', 'Mardoe, Ann']; // data
const search = '  joh  doe  '; // user input

// Remove extra spaces and create array
const searchArr = search.trim().replace(/\s+/g, ' ').split(' ');
const result = data.filter(item => searchArr.every(sa => new RegExp(sa, 'i').test(item)));

console.log(result)

Notice, if a person named "Doe, Doe" was in the list, the above would account it (since the length) for a "john doe" search, but I think it's fine.


问:
Filling a Java array with elements produced in another class
I'm trying to fill a deck of cards in my "Deck" class with cards created in my "Card" class. When I print the result in my Deck class, I get 52 "null"s, which tells me the two are communicating, just not very well. I've copied the code below. Where am I going wrong? Thanks!</p>

```<code>public class Card {
    public String cardName;
    private int[] cardValue = {(Integer) null, 1, 2, 3, 4, 5, 6, 7, 8,
        9, 10, 11};
    private String[] cardSuit = {"C", "D", "H", "S"};

    public Card(String cardName, int[] cardValue, String[] cardSuit) {
        this.cardName = cardName;
        this.cardValue = cardValue;
        this.cardSuit = cardSuit;
    }
    public String makeCard(int[] cardValue, String[] cardSuit) {
        for(int i = 0; i < 12; i++) {
            for(int j = 0; j < 4; j++) {
                cardName = cardValue[i] + cardSuit[j];
                j++;
            }
            i++;
        }
        return cardName;
    }
}
</code>```

```<code>import java.util.Arrays;

public class Deck {

    public static String[] cardDeck = new String[52];

    public String[] makeDeck(String cardName) {
        for(int i =0; i < 52; i++) {
            cardDeck[i] = cardName;
            i++;
        }

        Arrays.fill(cardDeck, cardName);
        return cardDeck;
    }

    public static void main(String[] args) {
        System.out.println(Arrays.toString(cardDeck));
    }
}
</code>```

答:
Your two classes are still independent. I've modified your code as follows:

```<code>public class Card {
    private String[] cardDeck = new String[52];
    private int[] cardValue = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
    private String[] cardSuit = {"C", "D", "H", "S"};

    public String[] makeDeck() {
        int c = 0;
        for (int i = 0; i < cardValue.length; i++) {
            for (int j = 0; j < cardSuit.length; j++) {
                cardDeck[c] = cardSuit[j] + cardValue[i];
                c++;
            }
        }
        return cardDeck;
    }
}
</code>```

```<code>import java.util.Arrays;

public class Deck {
    public static void main(String[] args) {
        Card card = new Card();
        System.out.println(Arrays.toString(card.makeDeck()));
    }
}
</code>```

The makeDeck method in Card class will now initialize the deck by iterating over each card value in a deck and the result will be appended to the cardDeck String array.

Further, the Deck Class calls this method and displays the deck.

Body:
I'm trying to fill a deck of cards in my "Deck" class with cards created in my "Card" class. When I print the result in my Deck class, I get 52 "null"s, which tells me the two are communicating, just not very well. I've copied the code below. Where am I going wrong? Thanks!

public class Card {
    public String cardName;
    private int[] cardValue = {(Integer) null, 1, 2, 3, 4, 5, 6, 7, 8,
        9, 10, 11};
    private String[] cardSuit = {"C", "D", "H", "S"};

    public Card(String cardName, int[] cardValue, String[] cardSuit) {
        this.cardName = cardName;
        this.cardValue = cardValue;
        this.cardSuit = cardSuit;
    }
    public String makeCard(int[] cardValue, String[] cardSuit) {
        for(int i = 0; i < 12; i++) {
            for(int j = 0; j < 4; j++) {
                cardName = cardValue[i] + cardSuit[j];
                j++;
            }
            i++;
        }
        return cardName;
    }
}

import java.util.Arrays;

public class Deck {

    public static String[] cardDeck = new String[52];

    public String[] makeDeck(String cardName) {
        for(int i =0; i < 52; i++) {
            cardDeck[i] = cardName;
            i++;
        }

        Arrays.fill(cardDeck, cardName);
        return cardDeck;
    }

    public static void main(String[] args) {
        System.out.println(Arrays.toString(cardDeck));
    }
}

Body:
Your two classes are still independent. I've modified your code as follows:

public class Card {
    private String[] cardDeck = new String[52];
    private int[] cardValue = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
    private String[] cardSuit = {"C", "D", "H", "S"};

    public String[] makeDeck() {
        int c = 0;
        for (int i = 0; i < cardValue.length; i++) {
            for (int j = 0; j < cardSuit.length; j++) {
                cardDeck[c] = cardSuit[j] + cardValue[i];
                c++;
            }
        }
        return cardDeck;
    }
}

import java.util.Arrays;

public class Deck {
    public static void main(String[] args) {
        Card card = new Card();
        System.out.println(Arrays.toString(card.makeDeck()));
    }
}

The makeDeck method in Card class will now initialize the deck by iterating over each card value in a deck and the result will be appended to the cardDeck String array.

Further, the Deck Class calls this method and displays the deck.


问:
seriate RequestError: SqlContext Error. Failed on step "GetData" with: "Timeout: Request failed to complete in 15000ms
I am trying to run a stored procedure on my SQL database from the node server using seriate. however i get the follwoing error and i am not sure why. I'd really appreciate your help on it.

Error: { [RequestError: SqlContext Error.
Failed on step "GetData" with: "Timeout: Request failed to complete i
15000ms"]
  name: 'RequestError',
  message: 'SqlContext Error. Failed on step "GetData" with: "Timeout
Request failed to complete in 15000ms"',
  code: 'ETIMEOUT',
  number: 'ETIMEOUT',
  lineNumber: undefined,
  state: undefined,
  class: undefined,
  serverName: undefined,
  procName: undefined,
  precedingErrors: [],
  step: 'GetData' }

This is my code:

```<code>var sql = require( "seriate" );

var connection = {
    name: "example-1",
    user: "user",
    password: "pass",
    host: "host_ip",
    database: "Test"
};

exports.getDataSql = function(req, res) {
    var results = {};

    sql.execute( connection, {
       procedure: "GetData",
        params: {
            Name: {
                type: sql.NVARCHAR(50),
                val: "user2"
            },
            LName: {
                type: sql.NVARCHAR(50),
                val: "user1"
            },
            finalName: {
                type: sql.NVARCHAR(50),
                val: "user3"
            }
        }
    }).then( function( results ) {
        console.log("getting data: ");
        res.json(results[0][0]);

    }, function( err ) {
        console.log( "Error", err );
        res.status(500).send({ error: 'Something failed!' });
    } );

};
</code>```

答: In my case the error is due to an uncommited transaction. Closing SQL Management Studio free the tables, since I had an error commiting a previous transaction from the editor.</p>

Body:
I am trying to run a stored procedure on my SQL database from the node server using seriate. however i get the follwoing error and i am not sure why. I'd really appreciate your help on it.

Error: { [RequestError: SqlContext Error.
Failed on step "GetData" with: "Timeout: Request failed to complete i
15000ms"]
  name: 'RequestError',
  message: 'SqlContext Error. Failed on step "GetData" with: "Timeout
Request failed to complete in 15000ms"',
  code: 'ETIMEOUT',
  number: 'ETIMEOUT',
  lineNumber: undefined,
  state: undefined,
  class: undefined,
  serverName: undefined,
  procName: undefined,
  precedingErrors: [],
  step: 'GetData' }

This is my code:

var sql = require( "seriate" );

var connection = {
    name: "example-1",
    user: "user",
    password: "pass",
    host: "host_ip",
    database: "Test"
};

exports.getDataSql = function(req, res) {
    var results = {};

    sql.execute( connection, {
       procedure: "GetData",
        params: {
            Name: {
                type: sql.NVARCHAR(50),
                val: "user2"
            },
            LName: {
                type: sql.NVARCHAR(50),
                val: "user1"
            },
            finalName: {
                type: sql.NVARCHAR(50),
                val: "user3"
            }
        }
    }).then( function( results ) {
        console.log("getting data: ");
        res.json(results[0][0]);

    }, function( err ) {
        console.log( "Error", err );
        res.status(500).send({ error: 'Something failed!' });
    } );

};


问:
Export / copy Access Pivot Table View to Excel 2003?
Is there a way to copy an Access 2003 pivot table view (used to pivot 206,000 records) to Excel 2003 using VBA?</p>

答: If all you need is a visible display of the data, such as the totals, Ctrl+C the selected range you want to show, then Shift+Edit+Paste Picture Link. When data is updated it will change the image. I would think you can adapt this to a macro, and generate what you want to distribute, fairly easily.</p>

ContentLicense: CC BY-SA 2.5


问:
Zoom/scale at mouse position
I am struggling to figure out and determine how to zoom on my mouse position based on this example. (https://stackblitz.com/edit/js-fxnmkm?file=index.js)

```<code>let node,
    scale = 1,
    posX = 0,
    posY = 0,
    node = document.querySelector('.frame');

const render = () => {
  window.requestAnimationFrame(() => {
    let val = `translate3D(${posX}px, ${posY}px, 0px) scale(${scale})`
    node.style.transform = val
  })
}

window.addEventListener('wheel', (e) => {
  e.preventDefault();

  // Zooming happens here
  if (e.ctrlKey) {
    scale -= e.deltaY * 0.01;
  } else {
    posX -= e.deltaX * 2;
    posY -= e.deltaY * 2;
  }

  render();
});
</code>```

My desired effect is based on this example (https://codepen.io/techslides/pen/zowLd?editors=0010) when zooming in. Currently my example above only scales to the center of the "viewport" but I want it to be where my cursor currently is.

I have searched high and low for a solution that is not implemented via canvas. Any help would be appreciated!

Caveat The reason why I am using the wheel event is to mimic the interaction of Figma (the design tool) panning and zooming.

答:
Use the canvas for zoomable content

Zooming and panning elements is very problematic. It can be done but the list of issues is very long. I would never implement such an interface.

Consider using the canvas, via 2D or WebGL to display such content to save your self many many problems.

The first part of the answer is implemented using the canvas. The same interface view is used in the second example that pans and zooms an element.

A simple 2D view.

As you are only panning and zooming then a very simple method can be used.

The example below implements an object called view. This holds the current scale and position (pan)

It provides two function for user interaction.

Panning the function view.pan(amount) will pan the view by distance in pixels held by amount.x, amount.y

Zooming the function view.scaleAt(at, amount) will scale (zoom in out) the view by amount (a number representing change in scale), at the position held by at.x, at.y in pixels.

In the example the view is applied to the canvas rendering context using view.apply() and a set of random boxes are rendered whenever the view changes.
The panning and zooming is via mouse events

Example using canvas 2D context

Use mouse button drag to pan, wheel to zoom

const ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;
const rand = (m = 255, M = m + (m = 0)) => (Math.random() * (M - m) + m) | 0;

const objects = [];
for (let i = 0; i < 100; i++) {
  objects.push({x: rand(canvas.width), y: rand(canvas.height),w: rand(40),h: rand(40), col: `rgb(${rand()},${rand()},${rand()})`});
}

requestAnimationFrame(drawCanvas);

const view = (() => {
  const matrix = [1, 0, 0, 1, 0, 0]; // current view transform
  var m = matrix;             // alias
  var scale = 1;              // current scale
  var ctx;                    // reference to the 2D context
  const pos = { x: 0, y: 0 }; // current position of origin
  var dirty = true;
  const API = {
    set context(_ctx) { ctx = _ctx; dirty = true },
    apply() {
      if (dirty) { this.update() }
      ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5])
    },
    get scale() { return scale },
    get position() { return pos },
    isDirty() { return dirty },
    update() {
      dirty = false;
      m[3] = m[0] = scale;
      m[2] = m[1] = 0;
      m[4] = pos.x;
      m[5] = pos.y;
    },
    pan(amount) {
      if (dirty) { this.update() }
       pos.x += amount.x;
       pos.y += amount.y;
       dirty = true;
    },
    scaleAt(at, amount) { // at in screen coords
      if (dirty) { this.update() }
      scale *= amount;
      pos.x = at.x - (at.x - pos.x) * amount;
      pos.y = at.y - (at.y - pos.y) * amount;
      dirty = true;
    },
  };
  return API;
})();
view.context = ctx;
function drawCanvas() {
    if (view.isDirty()) {
        ctx.setTransform(1, 0, 0, 1, 0, 0);
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        view.apply(); // set the 2D context transform to the view
        for (i = 0; i < objects.length; i++) {
            var obj = objects[i];
            ctx.fillStyle = obj.col;
            ctx.fillRect(obj.x, obj.y, obj.h, obj.h);
        }
    }
    requestAnimationFrame(drawCanvas);
}

canvas.addEventListener("mousemove", mouseEvent, {passive: true});
canvas.addEventListener("mousedown", mouseEvent, {passive: true});
canvas.addEventListener("mouseup", mouseEvent, {passive: true});
canvas.addEventListener("mouseout", mouseEvent, {passive: true});
canvas.addEventListener("wheel", mouseWheelEvent, {passive: false});
const mouse = {x: 0, y: 0, oldX: 0, oldY: 0, button: false};
function mouseEvent(event) {
    if (event.type === "mousedown") { mouse.button = true }
    if (event.type === "mouseup" || event.type === "mouseout") { mouse.button = false }
    mouse.oldX = mouse.x;
    mouse.oldY = mouse.y;
    mouse.x = event.offsetX;
    mouse.y = event.offsetY
    if(mouse.button) { // pan
        view.pan({x: mouse.x - mouse.oldX, y: mouse.y - mouse.oldY});
    }
}
function mouseWheelEvent(event) {
    var x = event.offsetX;
    var y = event.offsetY;
    if (event.deltaY < 0) { view.scaleAt({x, y}, 1.1) }
    else { view.scaleAt({x, y}, 1 / 1.1) }
    event.preventDefault();
}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>body {
  background: gainsboro;
  margin: 0;
}
canvas {
  background: white;
  box-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
}</code>```

<canvas id="canvas"></canvas>```
</div>
</div>
</p>
<h2>Example using <code>element.style.transform</code></h2>
<p>This example uses the element style transform property to zoom and pan.</p>
<ul>
<li><p><strong>Note</strong> that I use a 2D matrix rather than the 3d matrix as that can introduce many problems not compatible with the simple zoom and pan used below.</p>
</li>
<li><p><strong>Note</strong> that CSS transforms are not applied to the top left of the element in all cases. In the example below the origin is in the center of the element. Thus when zooming the <em>zoom at point</em> must be adjusted by subtracting half the elements size. The element size is not effected by the transform.</p>
</li>
<li><p><strong>Note</strong> borders, padding, and margins will also change the location of the origin. To work with <code>view.scaleAt(at, amount)</code> <code>at</code> must be relative to the top left most pixel of the element</p>
</li>
<li><p><strong>Note</strong> there are many more problems and caveats you need to consider when you zoom and pan elements, too many to fit in a single answer. That is why this answer starts with a canvas example as it is by far the safer method to managing zoom-able visual content.</p>
</li>
</ul>
<p>Use mouse button drag to pan, wheel to zoom. If you lose your position (zoom too far in out or panned of the page restart the snippet)</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const view = (() => {
  const matrix = [1, 0, 0, 1, 0, 0]; // current view transform
  var m = matrix;             // alias
  var scale = 1;              // current scale
  const pos = { x: 0, y: 0 }; // current position of origin
  var dirty = true;
  const API = {
    applyTo(el) {
      if (dirty) { this.update() }
      el.style.transform = `matrix(${m[0]},${m[1]},${m[2]},${m[3]},${m[4]},${m[5]})`;
    },
    update() {
      dirty = false;
      m[3] = m[0] = scale;
      m[2] = m[1] = 0;
      m[4] = pos.x;
      m[5] = pos.y;
    },
    pan(amount) {
      if (dirty) { this.update() }
       pos.x += amount.x;
       pos.y += amount.y;
       dirty = true;
    },
    scaleAt(at, amount) { // at in screen coords
      if (dirty) { this.update() }
      scale *= amount;
      pos.x = at.x - (at.x - pos.x) * amount;
      pos.y = at.y - (at.y - pos.y) * amount;
      dirty = true;
    },
  };
  return API;
})();

document.addEventListener("mousemove", mouseEvent, {passive: false});
document.addEventListener("mousedown", mouseEvent, {passive: false});
document.addEventListener("mouseup", mouseEvent, {passive: false});
document.addEventListener("mouseout", mouseEvent, {passive: false});
document.addEventListener("wheel", mouseWheelEvent, {passive: false});
const mouse = {x: 0, y: 0, oldX: 0, oldY: 0, button: false};
function mouseEvent(event) {
    if (event.type === "mousedown") { mouse.button = true }
    if (event.type === "mouseup" || event.type === "mouseout") { mouse.button = false }
    mouse.oldX = mouse.x;
    mouse.oldY = mouse.y;
    mouse.x = event.pageX;
    mouse.y = event.pageY;
    if(mouse.button) { // pan
        view.pan({x: mouse.x - mouse.oldX, y: mouse.y - mouse.oldY});
        view.applyTo(zoomMe);
    }
    event.preventDefault();
}
function mouseWheelEvent(event) {
    const x = event.pageX - (zoomMe.width / 2);
    const y = event.pageY - (zoomMe.height / 2);
    if (event.deltaY < 0) {
        view.scaleAt({x, y}, 1.1);
        view.applyTo(zoomMe);
    } else {
        view.scaleAt({x, y}, 1 / 1.1);
        view.applyTo(zoomMe);
    }
    event.preventDefault();
}</code>```

body {
   user-select: none;
   -moz-user-select: none;
}
.zoomables {
    pointer-events: none;
    border: 1px solid black;
}
#zoomMe {
    position: absolute;
    top: 0px;
    left: 0px;
}
  ```
<pre class="snippet-code-html lang-html prettyprint-override"><code><img id="zoomMe" class="zoomables" src="https://i.stack.imgur.com/C7qq2.png?s=328&g=1"></code>```

Title: Zoom/scale at mouse position

Body:
I am struggling to figure out and determine how to zoom on my mouse position based on this example. (https://stackblitz.com/edit/js-fxnmkm?file=index.js)

let node,
    scale = 1,
    posX = 0,
    posY = 0,
    node = document.querySelector('.frame');

const render = () => {
  window.requestAnimationFrame(() => {
    let val = `translate3D(${posX}px, ${posY}px, 0px) scale(${scale})`
    node.style.transform = val
  })
}

window.addEventListener('wheel', (e) => {
  e.preventDefault();

  // Zooming happens here
  if (e.ctrlKey) {
    scale -= e.deltaY * 0.01;
  } else {
    posX -= e.deltaX * 2;
    posY -= e.deltaY * 2;
  }

  render();
});

My desired effect is based on this example (https://codepen.io/techslides/pen/zowLd?editors=0010) when zooming in. Currently my example above only scales to the center of the "viewport" but I want it to be where my cursor currently is.

I have searched high and low for a solution that is not implemented via canvas. Any help would be appreciated!

Caveat The reason why I am using the wheel event is to mimic the interaction of Figma (the design tool) panning and zooming.

Body:
Use the canvas for zoomable content

Zooming and panning elements is very problematic. It can be done but the list of issues is very long. I would never implement such an interface.

Consider using the canvas, via 2D or WebGL to display such content to save your self many many problems.

The first part of the answer is implemented using the canvas. The same interface view is used in the second example that pans and zooms an element.

A simple 2D view.

As you are only panning and zooming then a very simple method can be used.

The example below implements an object called view. This holds the current scale and position (pan)

It provides two function for user interaction.

Panning the function view.pan(amount) will pan the view by distance in pixels held by amount.x, amount.y

Zooming the function view.scaleAt(at, amount) will scale (zoom in out) the view by amount (a number representing change in scale), at the position held by at.x, at.y in pixels.

In the example the view is applied to the canvas rendering context using view.apply() and a set of random boxes are rendered whenever the view changes.
The panning and zooming is via mouse events

Example using canvas 2D context

Use mouse button drag to pan, wheel to zoom

const ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;
const rand = (m = 255, M = m + (m = 0)) => (Math.random() * (M - m) + m) | 0;

const objects = [];
for (let i = 0; i < 100; i++) {
  objects.push({x: rand(canvas.width), y: rand(canvas.height),w: rand(40),h: rand(40), col: `rgb(${rand()},${rand()},${rand()})`});
}

requestAnimationFrame(drawCanvas);

const view = (() => {
  const matrix = [1, 0, 0, 1, 0, 0]; // current view transform
  var m = matrix;             // alias
  var scale = 1;              // current scale
  var ctx;                    // reference to the 2D context
  const pos = { x: 0, y: 0 }; // current position of origin
  var dirty = true;
  const API = {
    set context(_ctx) { ctx = _ctx; dirty = true },
    apply() {
      if (dirty) { this.update() }
      ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5])
    },
    get scale() { return scale },
    get position() { return pos },
    isDirty() { return dirty },
    update() {
      dirty = false;
      m[3] = m[0] = scale;
      m[2] = m[1] = 0;
      m[4] = pos.x;
      m[5] = pos.y;
    },
    pan(amount) {
      if (dirty) { this.update() }
       pos.x += amount.x;
       pos.y += amount.y;
       dirty = true;
    },
    scaleAt(at, amount) { // at in screen coords
      if (dirty) { this.update() }
      scale *= amount;
      pos.x = at.x - (at.x - pos.x) * amount;
      pos.y = at.y - (at.y - pos.y) * amount;
      dirty = true;
    },
  };
  return API;
})();
view.context = ctx;
function drawCanvas() {
    if (view.isDirty()) {
        ctx.setTransform(1, 0, 0, 1, 0, 0);
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        view.apply(); // set the 2D context transform to the view
        for (i = 0; i < objects.length; i++) {
            var obj = objects[i];
            ctx.fillStyle = obj.col;
            ctx.fillRect(obj.x, obj.y, obj.h, obj.h);
        }
    }
    requestAnimationFrame(drawCanvas);
}

canvas.addEventListener("mousemove", mouseEvent, {passive: true});
canvas.addEventListener("mousedown", mouseEvent, {passive: true});
canvas.addEventListener("mouseup", mouseEvent, {passive: true});
canvas.addEventListener("mouseout", mouseEvent, {passive: true});
canvas.addEventListener("wheel", mouseWheelEvent, {passive: false});
const mouse = {x: 0, y: 0, oldX: 0, oldY: 0, button: false};
function mouseEvent(event) {
    if (event.type === "mousedown") { mouse.button = true }
    if (event.type === "mouseup" || event.type === "mouseout") { mouse.button = false }
    mouse.oldX = mouse.x;
    mouse.oldY = mouse.y;
    mouse.x = event.offsetX;
    mouse.y = event.offsetY
    if(mouse.button) { // pan
        view.pan({x: mouse.x - mouse.oldX, y: mouse.y - mouse.oldY});
    }
}
function mouseWheelEvent(event) {
    var x = event.offsetX;
    var y = event.offsetY;
    if (event.deltaY < 0) { view.scaleAt({x, y}, 1.1) }
    else { view.scaleAt({x, y}, 1 / 1.1) }
    event.preventDefault();
}

body {
  background: gainsboro;
  margin: 0;
}
canvas {
  background: white;
  box-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
}

<canvas id="canvas"></canvas>

Example using element.style.transform

This example uses the element style transform property to zoom and pan.

Note that I use a 2D matrix rather than the 3d matrix as that can introduce many problems not compatible with the simple zoom and pan used below.

Note that CSS transforms are not applied to the top left of the element in all cases. In the example below the origin is in the center of the element. Thus when zooming the zoom at point must be adjusted by subtracting half the elements size. The element size is not effected by the transform.

Note borders, padding, and margins will also change the location of the origin. To work with view.scaleAt(at, amount) at must be relative to the top left most pixel of the element

Note there are many more problems and caveats you need to consider when you zoom and pan elements, too many to fit in a single answer. That is why this answer starts with a canvas example as it is by far the safer method to managing zoom-able visual content.

Use mouse button drag to pan, wheel to zoom. If you lose your position (zoom too far in out or panned of the page restart the snippet)

const view = (() => {
  const matrix = [1, 0, 0, 1, 0, 0]; // current view transform
  var m = matrix;             // alias
  var scale = 1;              // current scale
  const pos = { x: 0, y: 0 }; // current position of origin
  var dirty = true;
  const API = {
    applyTo(el) {
      if (dirty) { this.update() }
      el.style.transform = `matrix(${m[0]},${m[1]},${m[2]},${m[3]},${m[4]},${m[5]})`;
    },
    update() {
      dirty = false;
      m[3] = m[0] = scale;
      m[2] = m[1] = 0;
      m[4] = pos.x;
      m[5] = pos.y;
    },
    pan(amount) {
      if (dirty) { this.update() }
       pos.x += amount.x;
       pos.y += amount.y;
       dirty = true;
    },
    scaleAt(at, amount) { // at in screen coords
      if (dirty) { this.update() }
      scale *= amount;
      pos.x = at.x - (at.x - pos.x) * amount;
      pos.y = at.y - (at.y - pos.y) * amount;
      dirty = true;
    },
  };
  return API;
})();

document.addEventListener("mousemove", mouseEvent, {passive: false});
document.addEventListener("mousedown", mouseEvent, {passive: false});
document.addEventListener("mouseup", mouseEvent, {passive: false});
document.addEventListener("mouseout", mouseEvent, {passive: false});
document.addEventListener("wheel", mouseWheelEvent, {passive: false});
const mouse = {x: 0, y: 0, oldX: 0, oldY: 0, button: false};
function mouseEvent(event) {
    if (event.type === "mousedown") { mouse.button = true }
    if (event.type === "mouseup" || event.type === "mouseout") { mouse.button = false }
    mouse.oldX = mouse.x;
    mouse.oldY = mouse.y;
    mouse.x = event.pageX;
    mouse.y = event.pageY;
    if(mouse.button) { // pan
        view.pan({x: mouse.x - mouse.oldX, y: mouse.y - mouse.oldY});
        view.applyTo(zoomMe);
    }
    event.preventDefault();
}
function mouseWheelEvent(event) {
    const x = event.pageX - (zoomMe.width / 2);
    const y = event.pageY - (zoomMe.height / 2);
    if (event.deltaY < 0) {
        view.scaleAt({x, y}, 1.1);
        view.applyTo(zoomMe);
    } else {
        view.scaleAt({x, y}, 1 / 1.1);
        view.applyTo(zoomMe);
    }
    event.preventDefault();
}

body {
   user-select: none;
   -moz-user-select: none;
}
.zoomables {
    pointer-events: none;
    border: 1px solid black;
}
#zoomMe {
    position: absolute;
    top: 0px;
    left: 0px;
}

<img id="zoomMe" class="zoomables" src="https://i.stack.imgur.com/C7qq2.png?s=328&g=1">


问:
'TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined'
I'm working on a project in React and ran into a problem that has me stumped.

Whenever I run yarn start I get this error:

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type
string. Received type undefined

I have no idea why this is happening.

答:
I just had this issue after installing and removing some npm packages and spent almost 5 hours to figure out what was going on.

What I did is basically copied my src/components in a different directory, then removed all the node modules and package-lock.json (if you are running your app in the Docker container, remove images and rebuild it just to be safe); then reset it to my last commit and then put back my src/components then ran npm i.

I hope it helps.


问:
Is "git checkout -b branchName" the same as "git checkout --track origin/branchName"?
Is git checkout -b branchName the same as git checkout --track origin/branchName?   I'm trying to begin contributing to a remote branch from my local machine.  Are these commands equivalent?  If not, how do they differ?

答:
These options are a little different.

git checkout -b BRANCHNAME creates a new branch pointing to the same place as the current one and checks it out.  In other words, the new branch you've just created is generally equivalent to the old one (until you add more commmits).  The branch has no remote tracking branch associated with it.

With -b, it's also possible to specify a branch to base it off of, so you can use git branch -b bug-1234 project-5678 to create bug-1234 starting with project-5678.

git checkout --track REMOTE/BRANCHNAME creates a new branch (with the name BRANCHNAME) pointing to the same place as the remote tracking branch you specified.  The new branch has the specified remote tracking branch associated with it.  This implicitly uses -b under the hood if you don't specify it explicitly.

In general, if you want to just create a new branch off an existing one, use -b.  If you want to create a new branch that tracks a remote one, use --track.


问:
The Delete function works once, then unmounts from the rest of the elements [JavaScript Modules]
I've been practicing using JavaScript modules and I need somebody to help me understand why the delete function is not working properly. I'm assuming after I add a person, something happens in binding?

```<code>(function() {
  let people = {
    people: ['will', 'john'],
    init() {
      this.cacheDOM();
      this.render();
      this.bindingEvents();
    },
    cacheDOM() {
      this.$inputVal = document.getElementById('input');
      this.$target = document.getElementById('template');
      this.$button = document.getElementById('btn');
      this.$DOMLis = document.getElementsByClassName('elems');
    },
    bindingEvents() {
      this.$button.addEventListener('click', this.addName.bind(this));
      //Adding event listener "delete" to the lis
      this.$keys = Object.keys(this.$DOMLis);
      this.$keys.map(val => {
        this.$DOMLis[val].addEventListener('click', this.remove.bind(this));
      });
    },
    render() {
      this.$target.innerHTML =
        '<ul>' +
        this.people
          .map((val, i) => {
            return `<li key=${i} class='elems' name='${val}'>${val}</li>`;
          })
          .join('') +
        '</ul>';
    },
    addName() {
      this.people.push(this.$inputVal.value);
      this.render();
    },
    remove(e) {
      let index = parseInt(e.target.getAttribute('key'));
        this.people.splice(index, 1);

      this.render();
    },
  };

  people.init();
})();
</code>```

And this is the HTML

```<code><div id="root">
  <div id="template"></div>
  <input id="input" type="text" />
  <button id="btn">un</button>
</div>

<script type="text/javascript" src="./script.js"></script>

</code>```

The addPerson function seems to work fine with everything else, but the delete function is not.

答:
Your bindingEvents() function adds a click event listener to each of the elems created by your render() function. The next time render() is called (after an add or remove), all elems are removed and recreated, but the listeners are not re-added.
You will need to either change the way that render() is working, or re-add the click event listeners to each of the elems, each time you render.

Body:
I've been practicing using JavaScript modules and I need somebody to help me understand why the delete function is not working properly. I'm assuming after I add a person, something happens in binding?

(function() {
  let people = {
    people: ['will', 'john'],
    init() {
      this.cacheDOM();
      this.render();
      this.bindingEvents();
    },
    cacheDOM() {
      this.$inputVal = document.getElementById('input');
      this.$target = document.getElementById('template');
      this.$button = document.getElementById('btn');
      this.$DOMLis = document.getElementsByClassName('elems');
    },
    bindingEvents() {
      this.$button.addEventListener('click', this.addName.bind(this));
      //Adding event listener "delete" to the lis
      this.$keys = Object.keys(this.$DOMLis);
      this.$keys.map(val => {
        this.$DOMLis[val].addEventListener('click', this.remove.bind(this));
      });
    },
    render() {
      this.$target.innerHTML =
        '
' +
        this.people
          .map((val, i) => {
            return `<li key=${i} class='elems' name='${val}'>${val}</li>`;
          })
          .join('') +
        '
';
    },
    addName() {
      this.people.push(this.$inputVal.value);
      this.render();
    },
    remove(e) {
      let index = parseInt(e.target.getAttribute('key'));
        this.people.splice(index, 1);

      this.render();
    },
  };

  people.init();
})();

And this is the HTML

  <input id="input" type="text" />
  <button id="btn">un</button>

The addPerson function seems to work fine with everything else, but the delete function is not.