问:
How to ensure Hangfire jobs scheduled just once in web farm
Every time I deploy my application I remove all recurring jobs and re-add them like the following:

```<code>JobStorage.Current.GetConnection().GetRecurringJobs().ForEach(x => RecurringJob.RemoveIfExists(x.Id));
....
MyJobs.ForEach(x => RecurringJob.AddOrUpdate<....
</code>```

I need to do this to get around activation issues where I change the version number of my assemblies with each deployment and after deploying “MyAssembly, 2.0.0.0”, the original records with “MyAssembly, 1.0.0.0” not longer activate correctly, so after every release (actually every App Pool restart), I remove the recurring jobs and reschedule them. All is well and good.

I’m looking to start running my jobs in a web farm and I'd like this code that removes the jobs and re-adds them to happen once per ‘environment’, not once per hangfire server so several servers are not competing and adding the same jobs over and over.

I could probably designate one instance as the ‘leader’ via a web.config setting and only the leader would perform the scheduling of jobs, but what if my ‘leader’ didn’t come online after a deployment. I’d also like all my config files to be identical and not to have to configure one as a ‘leader’ in my CD pipiline.

What’s the best way to handle this scenario - is there anything built in to Hangfire?

答:
Please have a look at Hangfire.RecurringJobCleanUpManager. It might give you an example of how to deal with rescheduling recurring jobs.

There is no magic under the hood. It basically fetches all current recurring jobs, removes those which are no more present in code as 'scheduled' (here in library: enforced) and then adds those which are in code but did not appear while fetching current recurring jobs.

This is as you can see close to what you have done, just nicely packed into few classes. There is no other way than this unless you want to manually tamper Hangfire's metadata to update assembly names, version etc.

I can't see problem tied to pararellism in this solution. This does happens once per server instance, but since one server instance altered the state and made it proper, next server instances will simply fetch the correct state and realize they don't need to do anything. This will effectively make it "once per environment".

Body:
Every time I deploy my application I remove all recurring jobs and re-add them like the following:

JobStorage.Current.GetConnection().GetRecurringJobs().ForEach(x => RecurringJob.RemoveIfExists(x.Id));
....
MyJobs.ForEach(x => RecurringJob.AddOrUpdate<....

I need to do this to get around activation issues where I change the version number of my assemblies with each deployment and after deploying “MyAssembly, 2.0.0.0”, the original records with “MyAssembly, 1.0.0.0” not longer activate correctly, so after every release (actually every App Pool restart), I remove the recurring jobs and reschedule them. All is well and good.

I’m looking to start running my jobs in a web farm and I'd like this code that removes the jobs and re-adds them to happen once per ‘environment’, not once per hangfire server so several servers are not competing and adding the same jobs over and over.

I could probably designate one instance as the ‘leader’ via a web.config setting and only the leader would perform the scheduling of jobs, but what if my ‘leader’ didn’t come online after a deployment. I’d also like all my config files to be identical and not to have to configure one as a ‘leader’ in my CD pipiline.

What’s the best way to handle this scenario - is there anything built in to Hangfire?


来源: stackexchange

问:
Understanding View.drawableStateChanged
Can anyone explain when exactly View.drawableStateChanged is called? I want to use it in conjunction with ViewGroup.setAddStatesFromChildren to make a complete ViewGroup "optically" focused, meaning e.g. change background color when e.g. an EditText of this ViewGroup gets focus.

When I implement View.drawableStateChanged it's called very often, how do I know that the current call is the one I care about? What's the advantage over settings focus listeners on the child Views?

答:
to make it simple, you want your whole Viewgroup be focused when one of its children is actually focused for that you only need ViewGroup.setAddStatesFromChildren
create a drawable file i call it view_focus in my code :

```<code><selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="true" android:state_focused="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/white"/>
            <corners android:radius="19dp"/>
            <stroke android:color="@color/green" android:width="2dp"/>
        </shape>
    </item>

    <item android:state_enabled="true" android:state_focused="false">
        <shape android:shape="rectangle">
            <solid android:color="@color/white"/>
            <corners android:radius="19dp"/>
            <stroke android:color="@color/black" android:width="2dp"/>
        </shape>
    </item>

</selector>
</code>```

now in your activity layout you have to pass the above drawable as a background both in your Viewgroup and its children like the following :

```<code>    <RelativeLayout
        android:background="@drawable/view_focus"
        android:layout_centerInParent="true"
        android:id="@+id/parentlayout"
        android:layout_width="300dp"
        android:layout_height="250dp">
        <EditText
            android:padding="5dp"
            android:textSize="20sp"
            android:layout_centerInParent="true"
            android:background="@drawable/view_focus"
            android:id="@+id/edit"
            android:layout_width="200dp"
            android:layout_height="wrap_content"/>
        <EditText
            android:padding="5dp"
            android:textSize="20sp"
            android:layout_centerInParent="true"
            android:background="@drawable/view_focus"
            android:layout_below="@+id/edit"
            android:layout_marginTop="20dp"
            android:layout_width="200dp"
            android:layout_height="wrap_content"/>

    </RelativeLayout>
</code>```

in this case RelativeLayout parentlayout is the Viewgroup and it's children are the two EditText if you execute this code only the children will gain Focus once clicked, if you want your whole ViewGroup gain Focus your need to add this line in your Activity Class file :

```<code>relativeLayout = findViewById(R.id.parentlayout);
relativeLayout.setAddStatesFromChildren(true);
</code>```

this is the result after using the above line.

(source: fbcdn.net)

and this before using ViewGroup.setAddStatesFromChildren

(source: fbcdn.net)

ContentLicense: CC BY-SA 4.0

Title: Understanding View.drawableStateChanged

Body:
to make it simple, you want your whole Viewgroup be focused when one of its children is actually focused for that you only need ViewGroup.setAddStatesFromChildren
create a drawable file i call it view_focus in my code :

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="true" android:state_focused="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/white"/>
            <corners android:radius="19dp"/>
            <stroke android:color="@color/green" android:width="2dp"/>
        </shape>
    </item>

    <item android:state_enabled="true" android:state_focused="false">
        <shape android:shape="rectangle">
            <solid android:color="@color/white"/>
            <corners android:radius="19dp"/>
            <stroke android:color="@color/black" android:width="2dp"/>
        </shape>
    </item>

</selector>

now in your activity layout you have to pass the above drawable as a background both in your Viewgroup and its children like the following :

    <RelativeLayout
        android:background="@drawable/view_focus"
        android:layout_centerInParent="true"
        android:id="@+id/parentlayout"
        android:layout_width="300dp"
        android:layout_height="250dp">
        <EditText
            android:padding="5dp"
            android:textSize="20sp"
            android:layout_centerInParent="true"
            android:background="@drawable/view_focus"
            android:id="@+id/edit"
            android:layout_width="200dp"
            android:layout_height="wrap_content"/>
        <EditText
            android:padding="5dp"
            android:textSize="20sp"
            android:layout_centerInParent="true"
            android:background="@drawable/view_focus"
            android:layout_below="@+id/edit"
            android:layout_marginTop="20dp"
            android:layout_width="200dp"
            android:layout_height="wrap_content"/>

    </RelativeLayout>

in this case RelativeLayout parentlayout is the Viewgroup and it's children are the two EditText if you execute this code only the children will gain Focus once clicked, if you want your whole ViewGroup gain Focus your need to add this line in your Activity Class file :

relativeLayout = findViewById(R.id.parentlayout);
relativeLayout.setAddStatesFromChildren(true);

this is the result after using the above line.

(source: fbcdn.net)

and this before using ViewGroup.setAddStatesFromChildren

(source: fbcdn.net)


问:
How to display y-bar values in the bar chart?
Hello friends I am creating a bar chart using seaborn or matplotlib. I make a successful graph, but I don't know how to display y bar values on the plot. Please give me suggestion and different techniques to display y-bar values on the plot.

Please help me to solve the question.

Thank you

plt.figure(figsize = (10,5))
sns.countplot(x='subject',data=udemy,hue='is_paid')
```

答:
Unfortunately countplot in seaborn doesn't allow both x and y values to be passed, only one can be passed per plot.

Have you tried a different chart?
e.g. plt.bar() and setting the xticks and yticks to the values you want?


问:
Android Studio, how to see "tips(quick documentation)"?
I've been coding in Android Studio for a while now, be as in Kotlin and currently in Flutter. Whenever I am watching tutorials or lectures I see some-how they make a small window pop up that kinda shows some info. Here is a quick screenshot what I'm talking about:

I'm just bit curious about that because I know in Flutter you can press alt+enter to wrap certain widgets in other widgets. How do I get that window up?

Kind regards,

Mike

答:
Use the following shortcut while your cursor is on the right place:

For mac:

```<code>Control(^) + j
</code>```

For others:

```<code>Ctrl+F1 or Ctrl+Q
</code>```

Body:
Use the following shortcut while your cursor is on the right place:

For mac:

Control(^) + j

For others:

Ctrl+F1 or Ctrl+Q


问:
Which way of iterating array and changing element by map is more efficient?
I have a question about map.As you know by using map we can iterate arrays and able to change the element of arrays.To do that there are two ways and I listed them below.Which way has less complexity and more performance?(In the examples arrays are not big but think about the real world like 500 elements in an array)

```<code>var numbers = [4, 9, 16, 25];
numbers=numbers.map(e=>{
 return e=e*2;
})
</code>```

In this approach assigning each returned value to current array.

```<code>numbers.map((e,a)=>{
  numbers[a]=e*2;
})
</code>```

In this one on each iteration we need to go to array by index to find element and I think this is worse than above but Im not sure.

答:
Semantically you need for or forEach when you do not need a new array.
For sufficiently small arrays there is no difference in performance

var numbers = [4, 9, 16, 25];
numbers.forEach((e,i)=> numbers[i] = e*2);
console.log(numbers)```

Body:
I have a question about map.As you know by using map we can iterate arrays and able to change the element of arrays.To do that there are two ways and I listed them below.Which way has less complexity and more performance?(In the examples arrays are not big but think about the real world like 500 elements in an array)

var numbers = [4, 9, 16, 25];
numbers=numbers.map(e=>{
 return e=e*2;
})

In this approach assigning each returned value to current array.

numbers.map((e,a)=>{
  numbers[a]=e*2;
})

In this one on each iteration we need to go to array by index to find element and I think this is worse than above but Im not sure.


问:
Time complexity of T(n) = T(n - 1) + (n - 1)^2
I am wondering what is the time complexity of this recurrence relation.</p>

答: Sorry if I'm writing with images, but I needed to include some math:


问:
ASP.NET Core 404 Error on IIS 10
I have a problem with ASP.NET Core web application running on IIS 10.
I am developing a Single Page Application with AngularJS.

The index.html loads perfectly but the backend requests are failing with 404 error code on the IIS 10. From Visual Studio with IIS Express it works perfectly.

Can anyone spot how can I fix the backend requests?

Here's my Program.cs

```<code>public static void Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .Build();

    host.Run();
}
</code>```

And here's my Configure method from Startup.cs

```<code>public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseDefaultFiles();

    app.UseStaticFiles();

    app.UseIdentity();

    // Custom middleware for Angular UI-Router
    app.Use(async (context, next) =>
    {
        if (!Path.HasExtension(context.Request.Path.Value)
        && context.Request.HttpContext.Request.Headers["X-Requested-With"] != "XMLHttpRequest"
        && context.Request.Method.ToUpper() != "POST"
        && context.Request.Method.ToUpper() != "PUT"
        && context.Request.Method.ToUpper() != "DELETE")
        {
            await context.Response.WriteAsync(File.ReadAllText(env.WebRootPath + "/index.html"));
        }

        await next();
    });

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "api/{controller=Home}/{action=Index}/{id?}");
    });
}
</code>```

答:
Had the same issue now which brought me to this page. In case anyone is having this issue now this was what fixed it for me:

Downloaded and installed dotnet-hosting-3.1.4-win from https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-aspnetcore-3.1.4-windows-hosting-bundle-installer

Downloaded and installed dotnet-sdk-2.2.207-win-x64 from https://dotnet.microsoft.com/download/dotnet-core/2.2

ContentLicense: CC BY-SA 3.0

Title: ASP.NET Core 404 Error on IIS 10

Body:
I have a problem with ASP.NET Core web application running on IIS 10.
I am developing a Single Page Application with AngularJS.

The index.html loads perfectly but the backend requests are failing with 404 error code on the IIS 10. From Visual Studio with IIS Express it works perfectly.

Can anyone spot how can I fix the backend requests?

Here's my Program.cs

public static void Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .Build();

    host.Run();
}

And here's my Configure method from Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseDefaultFiles();

    app.UseStaticFiles();

    app.UseIdentity();

    // Custom middleware for Angular UI-Router
    app.Use(async (context, next) =>
    {
        if (!Path.HasExtension(context.Request.Path.Value)
        && context.Request.HttpContext.Request.Headers["X-Requested-With"] != "XMLHttpRequest"
        && context.Request.Method.ToUpper() != "POST"
        && context.Request.Method.ToUpper() != "PUT"
        && context.Request.Method.ToUpper() != "DELETE")
        {
            await context.Response.WriteAsync(File.ReadAllText(env.WebRootPath + "/index.html"));
        }

        await next();
    });

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "api/{controller=Home}/{action=Index}/{id?}");
    });
}


答:
Don't use map if you're not going to use the array it creates. If you just want to loop through an array, use a loop or forEach or similar.

Whether you want a new array or not, the most efficient way to loop through an array is usually a for loop:

```<code>const numbers = [4, 9, 16, 25];
for (let i = 0, len = numbers.length; i < len; ++i) {
    numbers[i] = numbers[i] * 2;
}
</code>```

(Or any of several variations on that.)

But "most efficient" is extremely unlikely to actually matter in real-world code, so using things like map (if you want a new array) or forEach (if you don't) is just fine. map is idiomatic for that operation (creating a new array containing the entries from a previous array modified in some way).

Conclusion:

If you want a new array, feel free to use map, or create a blank array and use any of your options for looping arrays to loop the original and add entries to the new one.

If you don't want a new array, don't use map, use any of your options for iterating over the original except for ones that don't give you the index, and assign the updated value back to the entry.

Title: Which way of iterating array and changing element by map is more efficient?

Body:
Don't use map if you're not going to use the array it creates. If you just want to loop through an array, use a loop or forEach or similar.

Whether you want a new array or not, the most efficient way to loop through an array is usually a for loop:

const numbers = [4, 9, 16, 25];
for (let i = 0, len = numbers.length; i < len; ++i) {
    numbers[i] = numbers[i] * 2;
}

(Or any of several variations on that.)

But "most efficient" is extremely unlikely to actually matter in real-world code, so using things like map (if you want a new array) or forEach (if you don't) is just fine. map is idiomatic for that operation (creating a new array containing the entries from a previous array modified in some way).

Conclusion:

If you want a new array, feel free to use map, or create a blank array and use any of your options for looping arrays to loop the original and add entries to the new one.

If you don't want a new array, don't use map, use any of your options for iterating over the original except for ones that don't give you the index, and assign the updated value back to the entry.


问:
Javascript Timer with input
I am trying to create a interactive timer that can be able to receive input.
How do I add an input to this code below so I am able to get a time(like in minutes) from a user so that I can time the timer?

HTML

```<code><!DOCTYPE html>
<html lang="en">
<head>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
    <link href="styles.css" rel="stylesheet">
    <title>Timer</title>
</head>
<script src='homepage.js'></script>
<body>
    <nav aria-label="breadcrumb">
        <ol class="breadcrumb">
            <li class="breadcrumb-item"><a href="index.html">Home</a></li>
            <li class="breadcrumb-item active" aria-current="page">Timer</li>
          </ol>
    </nav>
    <center>
        <div>
            <form onsubmit="timer(); return false;">
                <input type="submit" value='Start' class='button button1'>
            </form>
            <h1 id='demo'></h1>
            <form onsubmit="stopper();">
                <input type="submit" value='Stop' class='button button2'>
            </form>
        </div>
    </center>
</body>
</code>```

Javascript

```<code>function stopper() {
    let stop = true;
}

let stop = false;
function timer() {

    // Set the date we're counting down to
    var countDownDate = new Date("Jan 5, 2021 15:37:25").getTime();

    // Update the count down every 1 second
    var x = setInterval(function() {

        // Get today's date and time
        var now = new Date().getTime();

        // Find the distance between now and the count down date
        var distance = countDownDate - now;

        // Time calculations for days, hours, minutes and seconds
        var days = Math.floor(distance / (1000 * 60 * 60 * 24));
        var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
        var seconds = Math.floor((distance % (1000 * 60)) / 1000);

        // Display the result in the element with id="demo"
        document.getElementById("demo").innerHTML = days + " : " + hours + " : " + minutes + " : " + seconds;

        // If the count down is finished, write some text
        if (distance < 0) {
            document.getElementById("demo").innerHTML = 'Times up!';
            alert('Times up!');
        }
    }, 1000);
    if (stop === true) {
        return;
    }
}
</code>```

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

答:
Try the following snippet by replacing console.log with actual logic.

```<code>setTimeout(() => {
    console.log('logic timedout')
}, parseInt(prompt()) * 1000)
</code>```

Title: Javascript Timer with input

Body:
I am trying to create a interactive timer that can be able to receive input.
How do I add an input to this code below so I am able to get a time(like in minutes) from a user so that I can time the timer?

HTML

<!DOCTYPE html>

    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
    <link href="styles.css" rel="stylesheet">
    <title>Timer</title>

Home

Timer

            <form onsubmit="timer(); return false;">
                <input type="submit" value='Start' class='button button1'>
            </form>

            <form onsubmit="stopper();">
                <input type="submit" value='Stop' class='button button2'>
            </form>

Javascript

function stopper() {
    let stop = true;
}

let stop = false;
function timer() {

    // Set the date we're counting down to
    var countDownDate = new Date("Jan 5, 2021 15:37:25").getTime();

    // Update the count down every 1 second
    var x = setInterval(function() {

        // Get today's date and time
        var now = new Date().getTime();

        // Find the distance between now and the count down date
        var distance = countDownDate - now;

        // Time calculations for days, hours, minutes and seconds
        var days = Math.floor(distance / (1000 * 60 * 60 * 24));
        var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
        var seconds = Math.floor((distance % (1000 * 60)) / 1000);

        // Display the result in the element with id="demo"
        document.getElementById("demo").innerHTML = days + " : " + hours + " : " + minutes + " : " + seconds;

        // If the count down is finished, write some text
        if (distance < 0) {
            document.getElementById("demo").innerHTML = 'Times up!';
            alert('Times up!');
        }
    }, 1000);
    if (stop === true) {
        return;
    }
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Body:
Try the following snippet by replacing console.log with actual logic.

setTimeout(() => {
    console.log('logic timedout')
}, parseInt(prompt()) * 1000)


问:
Redshift has sortkey option when creating a table to improve query performance, does DolphinDB has similar mechanism?
I was an user of Redshift. I'm starting to use DolphinDB recently. I was wondering if DolphinDB has similar mechanism like in Redshift using sortkeys to improve query filtering. If so, what are they?</p>

答: Similarly, In DolphinDB, group by partition column will likely increase query performance. </p>


问:
Python parser using Regex for a course catalog
I've been trying to develop a type of parser for old course catalogs and have an idea of what I want to do but cannot figure it out.  Basically, the premise is that I want to parse and find the course abbreviations, so Computer Science would be abbreviated as "(CSC)."  Next, I would need to find the course numbers, course title, and course units.  My regex pattern for these are simple:

```<code>course_abbrev = re.compile('\([A-Z]{3}\)')
course_num = re.compile('[0-9]{3},?')
course_title = re.compile('.+?(?=I )')
course_units = re.compile('\d')
</code>```

The format of the catalogs all differ slightly, but they are relatively as followed:

```<code>"""
Computer Science (CSC)
Chairman: ...
201 Introduction to Computing I, 3
(Information of the course)...

220 Another Comp Class I, 3
(Information)...
...
...
...

Dental Hygiene (DHY)
Chairman: ...
101...
"""
</code>```

The text of the catalog is somewhat jumbled because it is being read via PyPDF2 since the catalogs are in PDF format but as such I am reading a page at a time of information. What would an efficient method be to go about finding the abbreviations, finding the number after that abbreviation, to then find the title after that number, and then the course unit.  The re module has ways to list all of these patterns (re.findall()) or search for one of them (re.search()) but I am unsure how to go about finding one, storing it, and then finding a different regex pattern from there, storing it, etc.

EDIT: The input looks like this thanks to PyPDF2, with pages being broken up and separating chunks of information:

```<code>COMPUTER SCIENCE (CSC)
CHAIRMAN: Professor Name (Computer Science
and Experimental Statistics)
201 Introduction
to Computing I and II, 3
Algorithms, programs, and computers. Basic
ming and program structure, data representation,
zation and characteristics of computers. Computer
tion of other stuff...
(Lee. 3). Staff 220 Computers in Society
II, 3 History, operation, application, and
social significance of
computers. Emphasis on the role of the computer in
ciety with respect to more information and dan
gers. (Lee. 3) Carrano
</code>```

答:
One option is to make use of the \G anchor to get iterative matches using the PyPi regex module.

While looping the matches, you can create a temporary list starting by adding the first group only when it is not None

Then add all other subsequent groups to it, and finally add the temporary list to the results list.

```<code>(?:^.* \(([A-Z]{3})\).*|\G(?!^))(?:\r?\n(?!\d{3} |.* \([A-Z]{3}\)[^\S\r\n]*$).*)*\r?\n(\d{3}) (.*?) I, (\d+)
</code>```

Explanation

(?: Non capture group

^.* \(([A-Z]{3})\).* Start of string and capture in group 1 three times an uppercase char A-Z

| Or

\G(?!^) Assert the positive at the end of the previous match, not at the start

) Close group

(?: Non capture group

\r?\n(?! Match a newline and assert that the string does not contain

\d{3}  Match 3 digits and space

| OR

.* \([A-Z]{3}\)[^\S\r\n]*$).* Match 3 uppercase chars A-Z at the end of the string

)* Close group and repeat that 0 or more times

\r?\n Match a newline

(\d{3}) (.*?) I, (\d+) Match in 3 groups: 3 digits all before the capital I and 1+ digits after the I and a comma and space

Regex demo and a Python demo

Example code

```<code>import regex

pattern = r"(?:^.* \(([A-Z]{3})\).*|\G(?!^))(?:\r?\n(?!\d{3} |.* \([A-Z]{3}\)[^\S\r\n]*$).*)*\r?\n(\d{3}) (.*?) I, (\d+)"

test_str = ("Computer Science (CSC)\n"
            "Chairman: ...\n"
            "201 Introduction to Computing I, 3\n"
            "(Information of the course)...\n\n"
            "220 Another Comp Class I, 3\n"
            "(Information)... \n"
            "...  \n"
            "...\n"
            "...\n\n"
            "Dental Hygiene (DHY)  \n"
            "Chairman: ...\n"
            "101 Introduction to Computing I, 3\n"
            "(Information of the course)...\n\n"
            "220 Another Comp Class I, 3\n"
            "(Information)... ")

matches = regex.finditer(pattern, test_str)
results = []
firstGroup = None

for matchNum, match in enumerate(matches, start=1):
    if match.group(1) is not None:
        firstGroup = match.group(1)

    tempList = [firstGroup]
    for groupNum in range(1, len(match.groups())):
        groupNum = groupNum + 1
        tempList.append(match.group(groupNum))
    results.append(tempList)
print(results)
</code>```

Output

```<code>[['CSC', '201', 'Introduction to Computing', '3'], ['CSC', '220', 'Another Comp Class', '3'], ['CSC', '101', 'Introduction to Computing', '3'], ['CSC', '220', 'Another Comp Class', '3']]
</code>```

Body:
I've been trying to develop a type of parser for old course catalogs and have an idea of what I want to do but cannot figure it out.  Basically, the premise is that I want to parse and find the course abbreviations, so Computer Science would be abbreviated as "(CSC)."  Next, I would need to find the course numbers, course title, and course units.  My regex pattern for these are simple:

course_abbrev = re.compile('\([A-Z]{3}\)')
course_num = re.compile('[0-9]{3},?')
course_title = re.compile('.+?(?=I )')
course_units = re.compile('\d')

The format of the catalogs all differ slightly, but they are relatively as followed:

"""
Computer Science (CSC)
Chairman: ...
201 Introduction to Computing I, 3
(Information of the course)...

220 Another Comp Class I, 3
(Information)...
...
...
...

Dental Hygiene (DHY)
Chairman: ...
101...
"""

The text of the catalog is somewhat jumbled because it is being read via PyPDF2 since the catalogs are in PDF format but as such I am reading a page at a time of information. What would an efficient method be to go about finding the abbreviations, finding the number after that abbreviation, to then find the title after that number, and then the course unit.  The re module has ways to list all of these patterns (re.findall()) or search for one of them (re.search()) but I am unsure how to go about finding one, storing it, and then finding a different regex pattern from there, storing it, etc.

EDIT: The input looks like this thanks to PyPDF2, with pages being broken up and separating chunks of information:

COMPUTER SCIENCE (CSC)
CHAIRMAN: Professor Name (Computer Science
and Experimental Statistics)
201 Introduction
to Computing I and II, 3
Algorithms, programs, and computers. Basic
ming and program structure, data representation,
zation and characteristics of computers. Computer
tion of other stuff...
(Lee. 3). Staff 220 Computers in Society
II, 3 History, operation, application, and
social significance of
computers. Emphasis on the role of the computer in
ciety with respect to more information and dan
gers. (Lee. 3) Carrano

Body:
One option is to make use of the \G anchor to get iterative matches using the PyPi regex module.

While looping the matches, you can create a temporary list starting by adding the first group only when it is not None

Then add all other subsequent groups to it, and finally add the temporary list to the results list.

(?:^.* \(([A-Z]{3})\).*|\G(?!^))(?:\r?\n(?!\d{3} |.* \([A-Z]{3}\)[^\S\r\n]*$).*)*\r?\n(\d{3}) (.*?) I, (\d+)

Explanation

(?: Non capture group

^.* \(([A-Z]{3})\).* Start of string and capture in group 1 three times an uppercase char A-Z

| Or

\G(?!^) Assert the positive at the end of the previous match, not at the start

) Close group

(?: Non capture group

\r?\n(?! Match a newline and assert that the string does not contain

\d{3}  Match 3 digits and space

| OR

.* \([A-Z]{3}\)[^\S\r\n]*$).* Match 3 uppercase chars A-Z at the end of the string

)* Close group and repeat that 0 or more times

\r?\n Match a newline

(\d{3}) (.*?) I, (\d+) Match in 3 groups: 3 digits all before the capital I and 1+ digits after the I and a comma and space

Regex demo and a <a href="https://tio.run/##zZLBitswEIbveoqp6UHjdc16cwuEsHhhN1D2klMbJcU4siOIR0aSoUu3z57KSpxkcWiv1Uma@eb/R8O0b26naXI4qKbVxoGRtfzJWFs4Jw3BDEzE59NNGoPgfPX45fv61@Q3Ckzjd/HM5582iD4vzFyQf4mtz8J7oAdY4GojlsIIWseffR3GRzqwCDyN5wiLBHzgDiPGnLTuh3XGe/Mo103b@U5gWSpJpQSeL3MUFDG4OlG@K5RpCppCmqaj7MN9BgtyRm@70ilN4DQchRXVvfVkVMIXVGmvGHBdgdtJKHVnrMTgMPZ4uIdH0p4zQRvyfWHtv8V7ORgRffBm9HZsFH2S5Io9vLzVfmp@aE8v3/CG4N/Hlv3vY4uQMf8sd9L2i9pvblop2iq/MPy0wQkM@4TMSNvtXc@u1qxSxrpno7vWv181Sca8OgS9165JjjdQBJK6RprCSX4yS8C6wrhZhtPQoaqOcFr3cjxDUBb8p4Ls9PyJD44fC1iAnGzar8q6vsELvA65vrdA@976pkxBteRZAntJ/ErMckS8eJ5LZpfrHWTn/GCZFm0raXutxIcCxICfpjeQQyWy1ihy/JT2Xzkc/gA" rel="nofollow noreferrer">Python demo

Example code

import regex

pattern = r"(?:^.* \(([A-Z]{3})\).*|\G(?!^))(?:\r?\n(?!\d{3} |.* \([A-Z]{3}\)[^\S\r\n]*$).*)*\r?\n(\d{3}) (.*?) I, (\d+)"

test_str = ("Computer Science (CSC)\n"
            "Chairman: ...\n"
            "201 Introduction to Computing I, 3\n"
            "(Information of the course)...\n\n"
            "220 Another Comp Class I, 3\n"
            "(Information)... \n"
            "...  \n"
            "...\n"
            "...\n\n"
            "Dental Hygiene (DHY)  \n"
            "Chairman: ...\n"
            "101 Introduction to Computing I, 3\n"
            "(Information of the course)...\n\n"
            "220 Another Comp Class I, 3\n"
            "(Information)... ")

matches = regex.finditer(pattern, test_str)
results = []
firstGroup = None

for matchNum, match in enumerate(matches, start=1):
    if match.group(1) is not None:
        firstGroup = match.group(1)

    tempList = [firstGroup]
    for groupNum in range(1, len(match.groups())):
        groupNum = groupNum + 1
        tempList.append(match.group(groupNum))
    results.append(tempList)
print(results)

Output

[['CSC', '201', 'Introduction to Computing', '3'], ['CSC', '220', 'Another Comp Class', '3'], ['CSC', '101', 'Introduction to Computing', '3'], ['CSC', '220', 'Another Comp Class', '3']]


问:
Is this the right way to compute gradients of two losses from two different NN's in pytorch?
I have a NN defined in pytorch and I have created two instances of that net as self.actor_critic_r1 and self.actor_critic_r2. I calculate the losses of each net i.e. loss1 and loss2 and I sum it up and calculate the grads in the following way,

```<code>loss_r1 = value_loss_r1 + action_loss_r1 - dist_entropy_r1 * args.entropy_coef
loss_r2 = value_loss_r2 + action_loss_r2 - dist_entropy_r2 * args.entropy_coef
self.optimizer_r1.zero_grad()
self.optimizer_r2.zero_grad()
loss = loss_r1 + loss_r2
loss.backward()
self.optimizer_r1.step()
self.optimizer_r2.step()
clip_grad_norm_(self.actor_critic_r1.parameters(), args.max_grad_norm)
clip_grad_norm_(self.actor_critic_r2.parameters(), args.max_grad_norm)
</code>```

Alternatively, should I update the loss individually like this,

```<code>self.optimizer_r1.zero_grad()
(value_loss_r1 + action_loss_r1 - dist_entropy_r1 * args.entropy_coef).backward()
self.optimizer_r1.step()
clip_grad_norm_(self.actor_critic_r1.parameters(), args.max_grad_norm)
self.optimizer_r2.zero_grad()
(value_loss_r2 + action_loss_r2 - dist_entropy_r2 * args.entropy_coef).backward()
self.optimizer_r2.step()
clip_grad_norm_(self.actor_critic_r2.parameters(), args.max_grad_norm)
</code>```

I am not sure if this the right approach to update a network with multiple loss please provide your suggestion.

答:
It should be the sum approach. If there is no interplay then the gradient of the 'wrong' loss will be zero for the 'wrong' optimizer anyway, and if there is interplay you likely want to optimize for that interplay.

Only if you know that there is interplay but you do not want to optimize for it should you use approach #2.

Body:
I have a NN defined in pytorch and I have created two instances of that net as self.actor_critic_r1 and self.actor_critic_r2. I calculate the losses of each net i.e. loss1 and loss2 and I sum it up and calculate the grads in the following way,

loss_r1 = value_loss_r1 + action_loss_r1 - dist_entropy_r1 * args.entropy_coef
loss_r2 = value_loss_r2 + action_loss_r2 - dist_entropy_r2 * args.entropy_coef
self.optimizer_r1.zero_grad()
self.optimizer_r2.zero_grad()
loss = loss_r1 + loss_r2
loss.backward()
self.optimizer_r1.step()
self.optimizer_r2.step()
clip_grad_norm_(self.actor_critic_r1.parameters(), args.max_grad_norm)
clip_grad_norm_(self.actor_critic_r2.parameters(), args.max_grad_norm)

Alternatively, should I update the loss individually like this,

self.optimizer_r1.zero_grad()
(value_loss_r1 + action_loss_r1 - dist_entropy_r1 * args.entropy_coef).backward()
self.optimizer_r1.step()
clip_grad_norm_(self.actor_critic_r1.parameters(), args.max_grad_norm)
self.optimizer_r2.zero_grad()
(value_loss_r2 + action_loss_r2 - dist_entropy_r2 * args.entropy_coef).backward()
self.optimizer_r2.step()
clip_grad_norm_(self.actor_critic_r2.parameters(), args.max_grad_norm)

I am not sure if this the right approach to update a network with multiple loss please provide your suggestion.


问:
Symfony 5 doctrine_migrations error on script boot
As far as i can tell, i can't see any other questions that ask this, so here goes:

I've been running the latest Symfony, for a side project, and encountered this error as i was writing the app. Nothing i do now fixes it, not even re-installing symfony, and i have no idea what the problem even is. I am getting the error:

The parameter "doctrine_migrations.dir_name" has a dependency on a
  non-existent parameter "kernel.root_dir". Did you mean one of these:
  "kernel.project_dir", "kernel.cache_dir", "kernel.logs_dir"?

答:
Just to document the root cause.

Symfony 5 removed kernel.root_dir parameters. Doctrine Migrations Bundle uses it as default value for dir_name.

It's been discussed. See https://github.com/doctrine/DoctrineMigrationsBundle/issues/305 and  https://github.com/doctrine/DoctrineMigrationsBundle/pull/295.

SOLUTION: right now (Symfony 5 and Migrations bundle 2.1.x), you should not delete doctrine_migrations.yaml. Leave it there with a dir_name that does not raise en error.


答:
nums.forEach((v, i) => nums[i] = v);
```

is the fastest method possible that you listed (equivalent to your second method. Why? nums = nums.map(...) creates an entire copy of the array in memory and replaces the array with that copy. When you simply iterate over the array with an index and replace elements, you avoid making that copy, and it ends up being around 15% faster (see this benchmark.

Body:
nums.forEach((v, i) => nums[i] = v);

is the fastest method possible that you listed (equivalent to your second method. Why? nums = nums.map(...) creates an entire copy of the array in memory and replaces the array with that copy. When you simply iterate over the array with an index and replace elements, you avoid making that copy, and it ends up being around 15% faster (see this benchmark.


问:
deploying zend framework application in mediatemple GS
i am having trouble deploying my zend framework application to mediatemple GS hosting.

I uploaded my application folder to ~/domains and renamed it to mysite.net folder.
Inside it, i created a symbolic link html which points to public directory in zend framework application folder. But the application is not working so far. Generally, mediatemple points a host to ~/domains/host/html path so my domain mysite.net should point to ~/domains/mysite.net/html.
Am i doing something wrong or is there more to this ? I am getting a 403 error when trying to access mysite.net

Update: Following rewrite rules make the base url http://mysite.net loadable but controllers dont work now. accessing http://mysite.net/controller sends page not found error :S

```<code>SetEnv APPLICATION_ENV development

RewriteEngine On
RewriteRule ^\.htaccess$ - [F]
RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ /public/index.php [NC,L]
RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ /public/$1
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]
RewriteRule ^public/.*$ /public/index.php [NC,L]
</code>```

Update: Its solved now. The trick is to add above .htaccess file to the application root folder and also keep the original .htaccess in public directory. Together they do wonders.

答:
I've found the solution myself:

create a .htaccess file in application root folder:

```<code>SetEnv APPLICATION_ENV development

RewriteEngine On
RewriteRule ^\.htaccess$ - [F]
RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ /public/index.php [NC,L]
RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ /public/$1
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]
RewriteRule ^public/.*$ /public/index.php [NC,L]
</code>```

Also keep the original .htaccess in the /public folder. I delete this at first which made things worse.

Body:
i am having trouble deploying my zend framework application to mediatemple GS hosting.

I uploaded my application folder to ~/domains and renamed it to mysite.net folder.
Inside it, i created a symbolic link html which points to public directory in zend framework application folder. But the application is not working so far. Generally, mediatemple points a host to ~/domains/host/html path so my domain mysite.net should point to ~/domains/mysite.net/html.
Am i doing something wrong or is there more to this ? I am getting a 403 error when trying to access mysite.net

Update: Following rewrite rules make the base url http://mysite.net loadable but controllers dont work now. accessing http://mysite.net/controller sends page not found error :S

SetEnv APPLICATION_ENV development

RewriteEngine On
RewriteRule ^\.htaccess$ - [F]
RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ /public/index.php [NC,L]
RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ /public/$1
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]
RewriteRule ^public/.*$ /public/index.php [NC,L]

Update: Its solved now. The trick is to add above .htaccess file to the application root folder and also keep the original .htaccess in public directory. Together they do wonders.

Body:
I've found the solution myself:

create a .htaccess file in application root folder:

SetEnv APPLICATION_ENV development

RewriteEngine On
RewriteRule ^\.htaccess$ - [F]
RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ /public/index.php [NC,L]
RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ /public/$1
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]
RewriteRule ^public/.*$ /public/index.php [NC,L]

Also keep the original .htaccess in the /public folder. I delete this at first which made things worse.


问:
How to convert the "Java modified UTF-8" to the regular UTF-8 and back?
I have created a Java wrapper around a native C library and have a question about the string encodings. There are slight differences in the “Java modified UTF-8” encoding that is used by Java from the regular UTF-8. And these differences may cause serious problems: the JNI functions may crash the app when passed the regular UTF-8 because it may contain byte sequences forbidden for the “Java modified UTF-8”. Please see the following topic: What does it mean to say "Java Modified UTF-8 Encoding"?

My question is what is a standard reliable way to convert the “Java modified UTF-8” to the regular UTF-8 and back?

答:
There is absolutely nothing that can only be achieved by using some library. You can always do it yourself.

Note: class Buffer below just wraps an array of byte the same way a String wraps an array of char.

```<code>public static String stringFromBuffer( Buffer buffer )
{
    String result = stringFromBuffer0( buffer );
    assert bufferFromString0( result ).equals( buffer );
    return result;
}

public static Buffer bufferFromString( String s )
{
    Buffer result = bufferFromString0( s );
    assert stringFromBuffer( result ).equals( s );
    return result;
}

private static String stringFromBuffer0( Buffer buffer )
{
    byte[] bytes = buffer.getBytes();
    int end = bytes.length;
    char[] chars = new char[end];
    int t = 0;
    for( int s = 0; s < end; )
    {
        int b1 = bytes[s++] & 0xff;
        assert b1 >> 4 >= 0;
        if( /*b1 >> 4 >= 0 &&*/ b1 >> 4 <= 7 ) /* 0x0xxx_xxxx */
            chars[t++] = (char)b1;
        else if( b1 >> 4 >= 8 && b1 >> 4 <= 11 ) /* 0x10xx_xxxx */
            throw new MalformedUtf8Exception( s - 1 );
        else if( b1 >> 4 >= 12 && b1 >> 4 <= 13 ) /* 0x110x_xxxx 0x10xx_xxxx */
        {
            assert s < end : new IncompleteUtf8Exception( s - 1 );
            int b2 = bytes[s++] & 0xff;
            assert (b2 & 0xc0) == 0x80 : new MalformedUtf8Exception( s - 1 );
            chars[t++] = (char)(((b1 & 0x1f) << 6) | (b2 & 0x3f));
        }
        else if( b1 >> 4 == 14 ) /* 0x1110_xxxx 0x10xx_xxxx 0x10xx_xxxx */
        {
            assert s < end : new IncompleteUtf8Exception( s - 1 );
            int b2 = bytes[s++] & 0xff;
            assert (b2 & 0xc0) == 0x80 : new MalformedUtf8Exception( s - 1 );
            assert s < end : new IncompleteUtf8Exception( s - 1 );
            int b3 = bytes[s++] & 0xff;
            assert (b3 & 0xc0) == 0x80 : new MalformedUtf8Exception( s - 1 );
            chars[t++] = (char)(((b1 & 0x0f) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f));
        }
        else /* 0x1111_xxxx */
            throw new MalformedUtf8Exception( s - 1 );
    }
    return new String( chars, 0, t );
}

private static Buffer bufferFromString0( String s )
{
    char[] chars = s.toCharArray();
    byte[] bytes = new byte[chars.length * 3];
    int p = 0;
    for( char c : chars )
    {
        if( (c >= 1) && (c <= 0x7f) )
            bytes[p++] = (byte)c;
        else if( c > 0x07ff )
        {
            bytes[p++] = (byte)(0xe0 | ((c >> 12) & 0x0f));
            bytes[p++] = (byte)(0x80 | ((c >> 6) & 0x3f));
            bytes[p++] = (byte)(0x80 | (c & 0x3f));
        }
        else
        {
            bytes[p++] = (byte)(0xc0 | ((c >> 6) & 0x1f));
            bytes[p++] = (byte)(0x80 | (c & 0x3f));
        }
    }
    if( p > 0xffff )
        throw new StringTooLongException( p );
    return Buffer.create( bytes, 0, p );
}
</code>```

Body:
There is absolutely nothing that can only be achieved by using some library. You can always do it yourself.

Note: class Buffer below just wraps an array of byte the same way a String wraps an array of char.

public static String stringFromBuffer( Buffer buffer )
{
    String result = stringFromBuffer0( buffer );
    assert bufferFromString0( result ).equals( buffer );
    return result;
}

public static Buffer bufferFromString( String s )
{
    Buffer result = bufferFromString0( s );
    assert stringFromBuffer( result ).equals( s );
    return result;
}

private static String stringFromBuffer0( Buffer buffer )
{
    byte[] bytes = buffer.getBytes();
    int end = bytes.length;
    char[] chars = new char[end];
    int t = 0;
    for( int s = 0; s < end; )
    {
        int b1 = bytes[s++] & 0xff;
        assert b1 >> 4 >= 0;
        if( /*b1 >> 4 >= 0 &&*/ b1 >> 4 <= 7 ) /* 0x0xxx_xxxx */
            chars[t++] = (char)b1;
        else if( b1 >> 4 >= 8 && b1 >> 4 <= 11 ) /* 0x10xx_xxxx */
            throw new MalformedUtf8Exception( s - 1 );
        else if( b1 >> 4 >= 12 && b1 >> 4 <= 13 ) /* 0x110x_xxxx 0x10xx_xxxx */
        {
            assert s < end : new IncompleteUtf8Exception( s - 1 );
            int b2 = bytes[s++] & 0xff;
            assert (b2 & 0xc0) == 0x80 : new MalformedUtf8Exception( s - 1 );
            chars[t++] = (char)(((b1 & 0x1f) << 6) | (b2 & 0x3f));
        }
        else if( b1 >> 4 == 14 ) /* 0x1110_xxxx 0x10xx_xxxx 0x10xx_xxxx */
        {
            assert s < end : new IncompleteUtf8Exception( s - 1 );
            int b2 = bytes[s++] & 0xff;
            assert (b2 & 0xc0) == 0x80 : new MalformedUtf8Exception( s - 1 );
            assert s < end : new IncompleteUtf8Exception( s - 1 );
            int b3 = bytes[s++] & 0xff;
            assert (b3 & 0xc0) == 0x80 : new MalformedUtf8Exception( s - 1 );
            chars[t++] = (char)(((b1 & 0x0f) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f));
        }
        else /* 0x1111_xxxx */
            throw new MalformedUtf8Exception( s - 1 );
    }
    return new String( chars, 0, t );
}

private static Buffer bufferFromString0( String s )
{
    char[] chars = s.toCharArray();
    byte[] bytes = new byte[chars.length * 3];
    int p = 0;
    for( char c : chars )
    {
        if( (c >= 1) && (c <= 0x7f) )
            bytes[p++] = (byte)c;
        else if( c > 0x07ff )
        {
            bytes[p++] = (byte)(0xe0 | ((c >> 12) & 0x0f));
            bytes[p++] = (byte)(0x80 | ((c >> 6) & 0x3f));
            bytes[p++] = (byte)(0x80 | (c & 0x3f));
        }
        else
        {
            bytes[p++] = (byte)(0xc0 | ((c >> 6) & 0x1f));
            bytes[p++] = (byte)(0x80 | (c & 0x3f));
        }
    }
    if( p > 0xffff )
        throw new StringTooLongException( p );
    return Buffer.create( bytes, 0, p );
}


问:
Overriding default timestamp names aren't working in Lumen 7
I have done this in model...

```<code>const CREATED_AT = 'creation_date';
const UPDATED_AT = 'last_update';
</code>```

And it doesn't work.

In migration file I have done...

```<code>$table->timestamps();
</code>```

答:
```<code>/**
 * Add nullable creation and update timestamps to the table.
 *
 * @param  int  $precision
 * @return void
 */
public function timestamps($precision = 0)
{
    $this->timestamp('created_at', $precision)->nullable();

    $this->timestamp('updated_at', $precision)->nullable();
}
</code>```

This is the timestamps method inside Illuminate\Database\Schema\Blueprint method. Overriding CREATED_AT or UPDATED_AT has nothing to do with that. It will create created_at and updated_at column in your table.

You may use timestamp such as $table->timestamp(MYMODEL:: CREATED_AT);

```<code>/**
 * Create a new timestamp column on the table.
 *
 * @param  string  $column
 * @param  int  $precision
 * @return \Illuminate\Database\Schema\ColumnDefinition
 */
public function timestamp($column, $precision = 0)
{
    return $this->addColumn('timestamp', $column, compact('precision'));
}
</code>```

Body:
I have done this in model...

const CREATED_AT = 'creation_date';
const UPDATED_AT = 'last_update';

And it doesn't work.

In migration file I have done...

$table->timestamps();

Body:
/**
 * Add nullable creation and update timestamps to the table.
 *
 * @param  int  $precision
 * @return void
 */
public function timestamps($precision = 0)
{
    $this->timestamp('created_at', $precision)->nullable();

    $this->timestamp('updated_at', $precision)->nullable();
}

This is the timestamps method inside Illuminate\Database\Schema\Blueprint method. Overriding CREATED_AT or UPDATED_AT has nothing to do with that. It will create created_at and updated_at column in your table.

You may use timestamp such as $table->timestamp(MYMODEL:: CREATED_AT);

/**
 * Create a new timestamp column on the table.
 *
 * @param  string  $column
 * @param  int  $precision
 * @return \Illuminate\Database\Schema\ColumnDefinition
 */
public function timestamp($column, $precision = 0)
{
    return $this->addColumn('timestamp', $column, compact('precision'));
}


问:
Rewrite the url of a website living in a subdirectory with .htaccess
I'm currently programming a website that, in a nutshell, loads its content dynamically via url parameters and php includes. The website is living under the root directory in a subfolder called "saischek".

The urls have one optional parameter: page, therefore the urls can for example look like this:

```<code>localhost/saischek/index.php?page=accounting
localhost/saischek/index.php
</code>```

I would like to have that my urls look like this:

```<code>localhost/saischek/accounting
localhost/saischek/home <- if the url parameter _page_ isn't given
</code>```

My .htaccess file is currently living in the subdirectory "saischek" and looks as follows:

```<code>RewriteEngine on
RewriteRule ^saischek/([a-zA-Z0-9_-]+)$ saischek/index.php?page=$1
</code>```

The website is running on apache webserver and all necessary changes in "httpd.conf" file are done and working.

答:
I'd say with the discussion in the comments to the question and your revision of the question you are nearly there, you found the solution yourself...

I would recommend to slightly change the main rule, also you will need to handle the "home" page you mentioned

```<code>RewriteEngine on
RewriteCond %{REQUEST_URI} !/saischek/index\.html$
RewriteRule ^/?saischek/home/?$ /saischek/index.php [QSA,END]
RewriteRule ^/?saischek/([a-zA-Z0-9_-]+)/?$ /saischek/index.php?page=$1 [QSA,END]
</code>```

I wonder however why you want to use the "home" slug at all, why not simply use https://example.org/saischek instead of https://example.org/saischek/home? In that case you would try this variant:

```<code>RewriteEngine on
RewriteCond %{REQUEST_URI} !/saischek/index\.html$
RewriteRule ^/?saischek/?$ /saischek/index.php [QSA,END]
RewriteRule ^/?saischek/([a-zA-Z0-9_-]+)/?$ /saischek/index.php?page=$1 [QSA,END]
</code>```

In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.

This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.

And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Body:
I'm currently programming a website that, in a nutshell, loads its content dynamically via url parameters and php includes. The website is living under the root directory in a subfolder called "saischek".

The urls have one optional parameter: page, therefore the urls can for example look like this:

localhost/saischek/index.php?page=accounting
localhost/saischek/index.php

I would like to have that my urls look like this:

localhost/saischek/accounting
localhost/saischek/home <- if the url parameter _page_ isn't given

My .htaccess file is currently living in the subdirectory "saischek" and looks as follows:

RewriteEngine on
RewriteRule ^saischek/([a-zA-Z0-9_-]+)$ saischek/index.php?page=$1

The website is running on apache webserver and all necessary changes in "httpd.conf" file are done and working.

Body:
I'd say with the discussion in the comments to the question and your revision of the question you are nearly there, you found the solution yourself...

I would recommend to slightly change the main rule, also you will need to handle the "home" page you mentioned

RewriteEngine on
RewriteCond %{REQUEST_URI} !/saischek/index\.html$
RewriteRule ^/?saischek/home/?$ /saischek/index.php [QSA,END]
RewriteRule ^/?saischek/([a-zA-Z0-9_-]+)/?$ /saischek/index.php?page=$1 [QSA,END]

I wonder however why you want to use the "home" slug at all, why not simply use https://example.org/saischek instead of https://example.org/saischek/home? In that case you would try this variant:

RewriteEngine on
RewriteCond %{REQUEST_URI} !/saischek/index\.html$
RewriteRule ^/?saischek/?$ /saischek/index.php [QSA,END]
RewriteRule ^/?saischek/([a-zA-Z0-9_-]+)/?$ /saischek/index.php?page=$1 [QSA,END]

In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.

This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.

And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).


问:
Concatenate rows with semicolon separator after grouping
I want to concatenate my result with semicolon separator so this is my query

```<code>SELECT
   Concat(Year(info.[CreationDate]),'/',Trim('BS-' from info.ProjectN)) As 'AllProjectN'
  ,part.Designation  As 'AllDesignation'
  ,cust.Name   As 'AllCustomer'
  ,prod.[Quantity] As 'AllQuantity'
  ,Case when prod.[Quantity] <=3 then prod.[Quantity]
                   when prod.[Quantity] between 4 and 501 then 3
                   when prod.[Quantity] between 502 and 1201 then 5
                   when prod.[Quantity] between 1202 and 1801 then 8
                   when prod.[Quantity] between 1802 and 3200 then 13
                   else ' ' end as 'Echantillonnage'
  ,[GalvaQualityDailyFicheControle].[CreationDate]

FROM [dbo].[GalvaQualityDailyFicheControle]
Inner Join GalvaQualityDailyProduction prod on prod.id= [GalvaQualityDailyFicheControle].FK_idDailyProduction
Inner join GalvaParts part on part.id=prod.[FK_idPart]
Inner join ProjectInfoGalva info on info.id=part.IdProject
inner Join Customer cust on cust.ID=info.FK_Customer

Where Convert(Date,[GalvaQualityDailyFicheControle].[CreationDate]) = '05-27-2020' AND [GalvaQualityDailyFicheControle].FK_idNextProcess=13
Group By
   Concat(Year(info.[CreationDate]),'/',Trim('BS-' from info.ProjectN))
  ,part.Designation
  ,cust.Name
  ,prod.[Quantity]
  ,[GalvaQualityDailyFicheControle].[CreationDate]
</code>```

I get this result

I try with STRING_AGG I get one row but the data is duplicated

```<code>SELECT
   STRING_AGG(Concat(Year(info.[CreationDate]),'/',Trim('BS-' from info.ProjectN))  , ' ;')As 'AllProjectN'
  ,STRING_AGG(part.Designation  , ' ;')As 'AllDesignation'
  ,STRING_AGG(cust.Name   , ' ;')As 'AllCustomer'
  ,STRING_AGG(prod.[Quantity] , ' ;')As 'AllQuantity'
  ,STRING_AGG(Case when prod.[Quantity] <=3 then prod.[Quantity]
                   when prod.[Quantity] between 4 and 501 then 3
                   when prod.[Quantity] between 502 and 1201 then 5
                   when prod.[Quantity] between 1202 and 1801 then 8
                   when prod.[Quantity] between 1802 and 3200 then 13
                   else ' ' end , ' ;')as 'Echantillonnage'
  ,[GalvaQualityDailyFicheControle].[CreationDate]

FROM [dbo].[GalvaQualityDailyFicheControle]
Inner Join GalvaQualityDailyProduction prod on prod.id=[GalvaQualityDailyFicheControle].FK_idDailyProduction
Inner join GalvaParts part on part.id=prod.[FK_idPart]
Inner join ProjectInfoGalva info on info.id=part.IdProject
inner Join Customer cust on cust.ID=info.FK_Customer

Where Convert(Date,[GalvaQualityDailyFicheControle].[CreationDate]) = '05-27-2020' AND [GalvaQualityDailyFicheControle].FK_idNextProcess=13
Group By
  [GalvaQualityDailyFicheControle].[CreationDate]
</code>```

This is the result I get

How can I get the one row without duplicate the data?.

答:
```<code>ALTER Proc [dbo].[RepDailyQualityGalvaFicheControleAll]
@Date date
AS
with myCTE
(AllProjectN,AllDesignation,AllCustomer,AllQuantity,Echantillonnage,CreationDate)AS
(
SELECT
   Concat(Year(info.[CreationDate]),'/',Trim('BS-' from info.ProjectN)) As 'AllProjectN'
  ,part.Designation  As 'AllDesignation'
  ,cust.Name   As 'AllCustomer'
  ,prod.[Quantity] As 'AllQuantity'
  ,Case when prod.[Quantity] <=3 then prod.[Quantity]
                   when prod.[Quantity] between 4 and 501 then 3
                   when prod.[Quantity] between 502 and 1201 then 5
                   when prod.[Quantity] between 1202 and 1801 then 8
                   when prod.[Quantity] between 1802 and 3200 then 13
                   else ' ' end as 'Echantillonnage'
  ,[GalvaQualityDailyFicheControle].[CreationDate]

FROM [dbo].[GalvaQualityDailyFicheControle]
Inner Join GalvaQualityDailyProduction prod on prod.id=[GalvaQualityDailyFicheControle].FK_idDailyProduction
Inner join GalvaParts part on part.id=prod.[FK_idPart]
Inner join ProjectInfoGalva info on info.id=part.IdProject
inner Join Customer cust on cust.ID=info.FK_Customer

Where Convert(Date,[GalvaQualityDailyFicheControle].[CreationDate]) = @Date AND [GalvaQualityDailyFicheControle].FK_idNextProcess=13
Group By
   Concat(Year(info.[CreationDate]),'/',Trim('BS-' from info.ProjectN))
  ,part.Designation
  ,cust.Name
  ,prod.[Quantity]
  ,[GalvaQualityDailyFicheControle].[CreationDate]
)
 Select STRING_AGG(AllProjectN, ' ;') AllProjectN
  ,STRING_AGG(AllDesignation, ' ;')AllDesignation
  ,STRING_AGG(AllCustomer, ' ;')AllCustomer
  ,STRING_AGG(AllQuantity, ' ;')AllQuantity
  ,STRING_AGG(Echantillonnage, ' ;')Echantillonnage
 ,CreationDate
FROM myCTE
Group By CreationDate
</code>```

Body:
I want to concatenate my result with semicolon separator so this is my query

SELECT
   Concat(Year(info.[CreationDate]),'/',Trim('BS-' from info.ProjectN)) As 'AllProjectN'
  ,part.Designation  As 'AllDesignation'
  ,cust.Name   As 'AllCustomer'
  ,prod.[Quantity] As 'AllQuantity'
  ,Case when prod.[Quantity] <=3 then prod.[Quantity]
                   when prod.[Quantity] between 4 and 501 then 3
                   when prod.[Quantity] between 502 and 1201 then 5
                   when prod.[Quantity] between 1202 and 1801 then 8
                   when prod.[Quantity] between 1802 and 3200 then 13
                   else ' ' end as 'Echantillonnage'
  ,[GalvaQualityDailyFicheControle].[CreationDate]

FROM [dbo].[GalvaQualityDailyFicheControle]
Inner Join GalvaQualityDailyProduction prod on prod.id= [GalvaQualityDailyFicheControle].FK_idDailyProduction
Inner join GalvaParts part on part.id=prod.[FK_idPart]
Inner join ProjectInfoGalva info on info.id=part.IdProject
inner Join Customer cust on cust.ID=info.FK_Customer

Where Convert(Date,[GalvaQualityDailyFicheControle].[CreationDate]) = '05-27-2020' AND [GalvaQualityDailyFicheControle].FK_idNextProcess=13
Group By
   Concat(Year(info.[CreationDate]),'/',Trim('BS-' from info.ProjectN))
  ,part.Designation
  ,cust.Name
  ,prod.[Quantity]
  ,[GalvaQualityDailyFicheControle].[CreationDate]

I get this result

I try with STRING_AGG I get one row but the data is duplicated

SELECT
   STRING_AGG(Concat(Year(info.[CreationDate]),'/',Trim('BS-' from info.ProjectN))  , ' ;')As 'AllProjectN'
  ,STRING_AGG(part.Designation  , ' ;')As 'AllDesignation'
  ,STRING_AGG(cust.Name   , ' ;')As 'AllCustomer'
  ,STRING_AGG(prod.[Quantity] , ' ;')As 'AllQuantity'
  ,STRING_AGG(Case when prod.[Quantity] <=3 then prod.[Quantity]
                   when prod.[Quantity] between 4 and 501 then 3
                   when prod.[Quantity] between 502 and 1201 then 5
                   when prod.[Quantity] between 1202 and 1801 then 8
                   when prod.[Quantity] between 1802 and 3200 then 13
                   else ' ' end , ' ;')as 'Echantillonnage'
  ,[GalvaQualityDailyFicheControle].[CreationDate]

FROM [dbo].[GalvaQualityDailyFicheControle]
Inner Join GalvaQualityDailyProduction prod on prod.id=[GalvaQualityDailyFicheControle].FK_idDailyProduction
Inner join GalvaParts part on part.id=prod.[FK_idPart]
Inner join ProjectInfoGalva info on info.id=part.IdProject
inner Join Customer cust on cust.ID=info.FK_Customer

Where Convert(Date,[GalvaQualityDailyFicheControle].[CreationDate]) = '05-27-2020' AND [GalvaQualityDailyFicheControle].FK_idNextProcess=13
Group By
  [GalvaQualityDailyFicheControle].[CreationDate]

This is the result I get

How can I get the one row without duplicate the data?.


问:
mkmap crashing when trying to get distance from user location to pin on map
For some reason whenever i click on my pin the app crashes. there are no errors or warnings in my code. It only happens when i try to get the distance from userLocation to the pin. find my mistake?

```<code>@implementation FirstViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
mapView.showsUserLocation = YES;

[super viewDidLoad];
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation   {

[self showPin];
[self updateLocation];
}
-(IBAction) updateLocation{
mapView.showsUserLocation = YES;
}
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc. that aren't in use.
}

- (void)viewDidUnload
{
[super viewDidUnload];

// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

-(IBAction)setMap:(id)sender{
switch(((UISegmentedControl *)sender).selectedSegmentIndex){
case 0:
{
    mapView.mapType = MKMapTypeStandard;
     break;
}
case 1:
{
    mapView.mapType = MKMapTypeSatellite;
    break;
}
case 2:
{
mapView.mapType = MKMapTypeHybrid;
break;
}

}}
- (void)dealloc
{
[super dealloc];
}
- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation {
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"pinView"];
if (!pinView) {
    pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pinView"] autorelease];
    pinView.pinColor = MKPinAnnotationColorRed;
    pinView.animatesDrop = YES;
    pinView.canShowCallout = YES;

    UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    pinView.rightCalloutAccessoryView = rightButton;
} else {
    pinView.annotation = annotation;
}
if (annotation == mapView.userLocation){
    return nil; //default to blue dot
}
return pinView;
}
-(IBAction) showPin{
//MOST CODE WILL BE INSERTED HERE!
//instructions

CLLocation *usersLocation = [[CLLocation alloc]initWithLatitude:mapView.userLocation.coordinate.latitude longitude:mapView.userLocation.coordinate.longitude];
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;
//ignore above
//always declare location as companyCity
//if more than one in one city then add a number i.e. companyCity2
//chili in mobile alabama
CLLocationCoordinate2D chiliAuburn = mapView.userLocation.coordinate;

chiliAuburn.latitude = 32.606434 ;
chiliAuburn.longitude = -85.484025;
region.span=span;
region.center=chiliAuburn;
CLLocation *chiliAuburnLocation = [[CLLocation alloc] initWithLatitude:chiliAuburn.latitude longitude:chiliAuburn.longitude];
if(chiliAuburnAlabama != nil) {
    [mapView removeAnnotation:chiliAuburnAlabama];
    [chiliAuburnAlabama release];
    chiliAuburnAlabama = nil;
}

chiliAuburnAlabama = [[AddressAnnotation alloc] initWithCoordinate:chiliAuburn];
[chiliAuburnAlabama setTitle:@"Chili Yogurt Café"];
double distanceMiles = ([usersLocation distanceFromLocation:chiliAuburnLocation]/1609.334);
[chiliAuburnAlabama setSubTitle:[NSString stringWithFormat:@"%.2fm", distanceMiles]];
//[chiliAuburnAlabama setSubTitle:@"TEST"];
[mapView addAnnotation:chiliAuburnAlabama];
[chiliAuburnAlabama release];
//tutti frutti homewood alabama
CLLocationCoordinate2D tuttifruttiHomewood = mapView.userLocation.coordinate;

tuttifruttiHomewood.latitude = 33.479775 ;
tuttifruttiHomewood.longitude = -86.790977;
region.span=span;
region.center=tuttifruttiHomewood;

if(tuttifruttiHomewoodAlabama != nil) {
    [mapView removeAnnotation:tuttifruttiHomewoodAlabama];
    [tuttifruttiHomewoodAlabama release];
    tuttifruttiHomewoodAlabama = nil;
}

tuttifruttiHomewoodAlabama = [[AddressAnnotation alloc] initWithCoordinate:tuttifruttiHomewood];
[tuttifruttiHomewoodAlabama setTitle:@"Tutti Frutti"];
[tuttifruttiHomewoodAlabama setSubTitle:@"YOUR RATING HERE"];
[mapView addAnnotation:tuttifruttiHomewoodAlabama];

//ignore below
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];

}
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views {
for(MKAnnotationView *annotationView in views) {
    if(annotationView.annotation == mv.userLocation) {
        MKCoordinateRegion region;
        MKCoordinateSpan span;

        span.latitudeDelta=0.1;
        span.longitudeDelta=0.1;

        CLLocationCoordinate2D location=mv.userLocation.coordinate;

        region.span=span;
        region.center=location;

        [mv setRegion:region animated:TRUE];
        [mv regionThatFits:region];
    }

}
}

@end
</code>```

GNU gdb 6.3.50-20050815 (Apple version gdb-1518) (Sat Feb 12 02:52:12 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin".Attaching to process 23386.
2011-06-02 00:39:46.146 YogurtStoreLocator[23386:207] 32.606434,-85.484025
2011-06-02 00:39:46.148 YogurtStoreLocator[23386:207] 33.479775,-86.790977
2011-06-02 00:39:53.121 YogurtStoreLocator[23386:207] -[NSCFNumber stringByStandardizingWhitespace]: unrecognized selector sent to instance 0x587b2d0
2011-06-02 00:39:53.123 YogurtStoreLocator[23386:207] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber stringByStandardizingWhitespace]: unrecognized selector sent to instance 0x587b2d0'
* Call stack at first throw:
(
    0   CoreFoundation                      0x00fca5a9 exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x0111e313 objc_exception_throw + 44
    2   CoreFoundation                      0x00fcc0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x00f3b966 __forwarding + 966
    4   CoreFoundation                      0x00f3b522 _CF_forwarding_prep_0 + 50
    5   UIKit                               0x0034c340 -[UICalloutView setSubtitle:animated:] + 88
    6   UIKit                               0x0034c010 -[UICalloutView setSubtitle:] + 49
    7   MapKit                              0x000bb0ac -[MKAnnotationContainerView _showBubbleForAnnotationView:bounce:scrollToFit:userInitiated:avoid:] + 537
    8   MapKit                              0x000bc3ed -[MKAnnotationContainerView _setSelectedAnnotationView:bounce:pressed:scrollToFit:userInitiated:avoid:] + 653
    9   MapKit                              0x000b54bc -[MKAnnotationContainerView _setSelectedAnnotationView:bounce:pressed:scrollToFit:userInitiated:] + 144
    10  MapKit                              0x0008cab3 -[MKMapView handleTap:] + 459
    11  UIKit                               0x004ad4f2 -[UIGestureRecognizer _updateGestureWithEvent:] + 730
    12  UIKit                               0x004a94fe -[UIGestureRecognizer _delayedUpdateGesture] + 47
    13  UIKit                               0x004afafc _UIGestureRecognizerUpdateObserver + 584
    14  CoreFoundation                      0x00fab89b CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 27
    15  CoreFoundation                      0x00f406e7 __CFRunLoopDoObservers + 295
    16  CoreFoundation                      0x00f091d7 __CFRunLoopRun + 1575
    17  CoreFoundation                      0x00f08840 CFRunLoopRunSpecific + 208
    18  CoreFoundation                      0x00f08761 CFRunLoopRunInMode + 97
    19  GraphicsServices                    0x01f071c4 GSEventRunModal + 217
    20  GraphicsServices                    0x01f07289 GSEventRun + 115
    21  UIKit                               0x0022ac93 UIApplicationMain + 1160
    22  YogurtStoreLocator                  0x00002099 main + 121
    23  YogurtStoreLocator                  0x00002015 start + 53
)
terminate called after throwing an instance of 'NSException'
sharedlibrary apply-load-rules all
Current language:  auto; currently objective-c
(gdb)

答: Just setting showsUserLocation to YES isn't sufficient. The map view needs to fetch that data. This is an asynchronous process and the data will be updated only after a while. The delegate is notified of this update via mapView:didUpdateUseLocation: method. You should implement that method and make a call to showPin only after you've the user location.

Body:
For some reason whenever i click on my pin the app crashes. there are no errors or warnings in my code. It only happens when i try to get the distance from userLocation to the pin. find my mistake?

@implementation FirstViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
mapView.showsUserLocation = YES;

[super viewDidLoad];
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation   {

[self showPin];
[self updateLocation];
}
-(IBAction) updateLocation{
mapView.showsUserLocation = YES;
}
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc. that aren't in use.
}

- (void)viewDidUnload
{
[super viewDidUnload];

// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

-(IBAction)setMap:(id)sender{
switch(((UISegmentedControl *)sender).selectedSegmentIndex){
case 0:
{
    mapView.mapType = MKMapTypeStandard;
     break;
}
case 1:
{
    mapView.mapType = MKMapTypeSatellite;
    break;
}
case 2:
{
mapView.mapType = MKMapTypeHybrid;
break;
}

}}
- (void)dealloc
{
[super dealloc];
}
- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation {
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"pinView"];
if (!pinView) {
    pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pinView"] autorelease];
    pinView.pinColor = MKPinAnnotationColorRed;
    pinView.animatesDrop = YES;
    pinView.canShowCallout = YES;

    UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    pinView.rightCalloutAccessoryView = rightButton;
} else {
    pinView.annotation = annotation;
}
if (annotation == mapView.userLocation){
    return nil; //default to blue dot
}
return pinView;
}
-(IBAction) showPin{
//MOST CODE WILL BE INSERTED HERE!
//instructions

CLLocation *usersLocation = [[CLLocation alloc]initWithLatitude:mapView.userLocation.coordinate.latitude longitude:mapView.userLocation.coordinate.longitude];
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;
//ignore above
//always declare location as companyCity
//if more than one in one city then add a number i.e. companyCity2
//chili in mobile alabama
CLLocationCoordinate2D chiliAuburn = mapView.userLocation.coordinate;

chiliAuburn.latitude = 32.606434 ;
chiliAuburn.longitude = -85.484025;
region.span=span;
region.center=chiliAuburn;
CLLocation *chiliAuburnLocation = [[CLLocation alloc] initWithLatitude:chiliAuburn.latitude longitude:chiliAuburn.longitude];
if(chiliAuburnAlabama != nil) {
    [mapView removeAnnotation:chiliAuburnAlabama];
    [chiliAuburnAlabama release];
    chiliAuburnAlabama = nil;
}

chiliAuburnAlabama = [[AddressAnnotation alloc] initWithCoordinate:chiliAuburn];
[chiliAuburnAlabama setTitle:@"Chili Yogurt Café"];
double distanceMiles = ([usersLocation distanceFromLocation:chiliAuburnLocation]/1609.334);
[chiliAuburnAlabama setSubTitle:[NSString stringWithFormat:@"%.2fm", distanceMiles]];
//[chiliAuburnAlabama setSubTitle:@"TEST"];
[mapView addAnnotation:chiliAuburnAlabama];
[chiliAuburnAlabama release];
//tutti frutti homewood alabama
CLLocationCoordinate2D tuttifruttiHomewood = mapView.userLocation.coordinate;

tuttifruttiHomewood.latitude = 33.479775 ;
tuttifruttiHomewood.longitude = -86.790977;
region.span=span;
region.center=tuttifruttiHomewood;

if(tuttifruttiHomewoodAlabama != nil) {
    [mapView removeAnnotation:tuttifruttiHomewoodAlabama];
    [tuttifruttiHomewoodAlabama release];
    tuttifruttiHomewoodAlabama = nil;
}

tuttifruttiHomewoodAlabama = [[AddressAnnotation alloc] initWithCoordinate:tuttifruttiHomewood];
[tuttifruttiHomewoodAlabama setTitle:@"Tutti Frutti"];
[tuttifruttiHomewoodAlabama setSubTitle:@"YOUR RATING HERE"];
[mapView addAnnotation:tuttifruttiHomewoodAlabama];

//ignore below
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];

}
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views {
for(MKAnnotationView *annotationView in views) {
    if(annotationView.annotation == mv.userLocation) {
        MKCoordinateRegion region;
        MKCoordinateSpan span;

        span.latitudeDelta=0.1;
        span.longitudeDelta=0.1;

        CLLocationCoordinate2D location=mv.userLocation.coordinate;

        region.span=span;
        region.center=location;

        [mv setRegion:region animated:TRUE];
        [mv regionThatFits:region];
    }

}
}

@end

GNU gdb 6.3.50-20050815 (Apple version gdb-1518) (Sat Feb 12 02:52:12 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin".Attaching to process 23386.
2011-06-02 00:39:46.146 YogurtStoreLocator[23386:207] 32.606434,-85.484025
2011-06-02 00:39:46.148 YogurtStoreLocator[23386:207] 33.479775,-86.790977
2011-06-02 00:39:53.121 YogurtStoreLocator[23386:207] -[NSCFNumber stringByStandardizingWhitespace]: unrecognized selector sent to instance 0x587b2d0
2011-06-02 00:39:53.123 YogurtStoreLocator[23386:207] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber stringByStandardizingWhitespace]: unrecognized selector sent to instance 0x587b2d0'
* Call stack at first throw:
(
    0   CoreFoundation                      0x00fca5a9 exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x0111e313 objc_exception_throw + 44
    2   CoreFoundation                      0x00fcc0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x00f3b966 __forwarding + 966
    4   CoreFoundation                      0x00f3b522 _CF_forwarding_prep_0 + 50
    5   UIKit                               0x0034c340 -[UICalloutView setSubtitle:animated:] + 88
    6   UIKit                               0x0034c010 -[UICalloutView setSubtitle:] + 49
    7   MapKit                              0x000bb0ac -[MKAnnotationContainerView _showBubbleForAnnotationView:bounce:scrollToFit:userInitiated:avoid:] + 537
    8   MapKit                              0x000bc3ed -[MKAnnotationContainerView _setSelectedAnnotationView:bounce:pressed:scrollToFit:userInitiated:avoid:] + 653
    9   MapKit                              0x000b54bc -[MKAnnotationContainerView _setSelectedAnnotationView:bounce:pressed:scrollToFit:userInitiated:] + 144
    10  MapKit                              0x0008cab3 -[MKMapView handleTap:] + 459
    11  UIKit                               0x004ad4f2 -[UIGestureRecognizer _updateGestureWithEvent:] + 730
    12  UIKit                               0x004a94fe -[UIGestureRecognizer _delayedUpdateGesture] + 47
    13  UIKit                               0x004afafc _UIGestureRecognizerUpdateObserver + 584
    14  CoreFoundation                      0x00fab89b CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 27
    15  CoreFoundation                      0x00f406e7 __CFRunLoopDoObservers + 295
    16  CoreFoundation                      0x00f091d7 __CFRunLoopRun + 1575
    17  CoreFoundation                      0x00f08840 CFRunLoopRunSpecific + 208
    18  CoreFoundation                      0x00f08761 CFRunLoopRunInMode + 97
    19  GraphicsServices                    0x01f071c4 GSEventRunModal + 217
    20  GraphicsServices                    0x01f07289 GSEventRun + 115
    21  UIKit                               0x0022ac93 UIApplicationMain + 1160
    22  YogurtStoreLocator                  0x00002099 main + 121
    23  YogurtStoreLocator                  0x00002015 start + 53
)
terminate called after throwing an instance of 'NSException'
sharedlibrary apply-load-rules all
Current language:  auto; currently objective-c
(gdb)


问:
create oracle sql cursor inside procedure ERROR
I created a procedure for calculating salary of employees by considering shift table data
my shift table is ,

```<code>CREATE TABLE SHIFT
        (SHIFT_ID NUMBER(4),
        SHIFT_DATE DATE,
        CUSTOMER_ID NUMBER(4),
        SERVICE_ID NUMBER(4),
        EMPLOYEE_ID  NUMBER(4),
        SHIFT_CHARGE FLOAT(10),
        PRIMARY KEY(SHIFT_ID)
        );
</code>```

my procedure is,

```<code>CREATE OR REPLACE PROCEDURE CAL_SALLARY
AS
CURSOR SHIFT_CURSOR IS SELECT EMPLOYEE_ID,SUM(SHIFT_CHARGE) AS SALARY FROM SHIFT GROUP BY EMPLOYEE_ID;
BEGIN
    OPEN SHIFT_CURSOR;
    LOOP
        FETCH SHIFT_CURSOR INTO SHIFT_REC;
        EXIT WHEN SHIFT_CURSOR%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('EMPLOYYE ID : '||SHIFT_REC.EMPLOYEE_ID||' SALARY : '||SHIFT_REC.SALARY);
    END LOOP;
    CLOSE SHIFT_CURSOR;
END;
/
</code>```

But when I try to run this procedure in SQL plus, it says compilation fails. I count found what's the issue.
 please anyone help me.

答:
You forgot to declare cursor variable (see line #7):

```<code>SQL> CREATE OR REPLACE PROCEDURE CAL_SALLARY
  2  AS
  3  CURSOR SHIFT_CURSOR IS
  4    SELECT EMPLOYEE_ID, SUM(SHIFT_CHARGE) AS SALARY
  5    FROM SHIFT GROUP BY EMPLOYEE_ID;
  6
  7    shift_Rec shift_cursor%rowtype;
  8  BEGIN
  9      OPEN SHIFT_CURSOR;
 10      LOOP
 11          FETCH SHIFT_CURSOR INTO SHIFT_REC;
 12          EXIT WHEN SHIFT_CURSOR%NOTFOUND;
 13          DBMS_OUTPUT.PUT_LINE('EMPLOYYE ID : '||SHIFT_REC.EMPLOYEE_ID
 14                                ||' SALARY : '||SHIFT_REC.SALARY);
 15      END LOOP;
 16      CLOSE SHIFT_CURSOR;
 17  END;
 18  /

Procedure created.

SQL>
</code>```

A simpler option is cursor FOR loop; Oracle does most of dirty job for you (e.g. declaring cursor variable, opening and closing cursor, exiting the loop):

```<code>SQL> create or replace procedure cal_sallary as
  2  begin
  3    for shift_rec in (select employee_id, sum(shift_charge) as salary
  4                      from shift
  5                      group by employee_id
  6                     )
  7    loop
  8      dbms_output.put_line('EMPLOYYE ID : '||shift_rec.employee_id
  9                           ||' SALARY : '||shift_rec.salary);
 10    end loop;
 11  end;
 12  /

Procedure created.

SQL>
</code>```

Body:
I created a procedure for calculating salary of employees by considering shift table data
my shift table is ,

CREATE TABLE SHIFT
        (SHIFT_ID NUMBER(4),
        SHIFT_DATE DATE,
        CUSTOMER_ID NUMBER(4),
        SERVICE_ID NUMBER(4),
        EMPLOYEE_ID  NUMBER(4),
        SHIFT_CHARGE FLOAT(10),
        PRIMARY KEY(SHIFT_ID)
        );

my procedure is,

CREATE OR REPLACE PROCEDURE CAL_SALLARY
AS
CURSOR SHIFT_CURSOR IS SELECT EMPLOYEE_ID,SUM(SHIFT_CHARGE) AS SALARY FROM SHIFT GROUP BY EMPLOYEE_ID;
BEGIN
    OPEN SHIFT_CURSOR;
    LOOP
        FETCH SHIFT_CURSOR INTO SHIFT_REC;
        EXIT WHEN SHIFT_CURSOR%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('EMPLOYYE ID : '||SHIFT_REC.EMPLOYEE_ID||' SALARY : '||SHIFT_REC.SALARY);
    END LOOP;
    CLOSE SHIFT_CURSOR;
END;
/

But when I try to run this procedure in SQL plus, it says compilation fails. I count found what's the issue.
 please anyone help me.

Body:
You forgot to declare cursor variable (see line #7):

SQL> CREATE OR REPLACE PROCEDURE CAL_SALLARY
  2  AS
  3  CURSOR SHIFT_CURSOR IS
  4    SELECT EMPLOYEE_ID, SUM(SHIFT_CHARGE) AS SALARY
  5    FROM SHIFT GROUP BY EMPLOYEE_ID;
  6
  7    shift_Rec shift_cursor%rowtype;
  8  BEGIN
  9      OPEN SHIFT_CURSOR;
 10      LOOP
 11          FETCH SHIFT_CURSOR INTO SHIFT_REC;
 12          EXIT WHEN SHIFT_CURSOR%NOTFOUND;
 13          DBMS_OUTPUT.PUT_LINE('EMPLOYYE ID : '||SHIFT_REC.EMPLOYEE_ID
 14                                ||' SALARY : '||SHIFT_REC.SALARY);
 15      END LOOP;
 16      CLOSE SHIFT_CURSOR;
 17  END;
 18  /

Procedure created.

SQL>

A simpler option is cursor FOR loop; Oracle does most of dirty job for you (e.g. declaring cursor variable, opening and closing cursor, exiting the loop):

SQL> create or replace procedure cal_sallary as
  2  begin
  3    for shift_rec in (select employee_id, sum(shift_charge) as salary
  4                      from shift
  5                      group by employee_id
  6                     )
  7    loop
  8      dbms_output.put_line('EMPLOYYE ID : '||shift_rec.employee_id
  9                           ||' SALARY : '||shift_rec.salary);
 10    end loop;
 11  end;
 12  /

Procedure created.

SQL>


问:
How to turn a table vertical using PHP
I am just learning PHP ,and I want to create a table that display echo data that I submit to my database , the problem I have that the table displayed horizontally by default as you see Horizontal default table this my script

Name
Age
Height

<?php
$conn = mysqli_connect("localhost", "root", "", "class");
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT Name, Age, Height FROM student order by Name desc";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "
" . $row["Name"]. "	" . $row["Age"] . "	"
. $row["Height"]. "
";
}
echo "
";
} else //{ echo "0 results"; }//
$conn->close();
?>

```

but I want it to be echoed vertically instead like this VERTICAL RESULT I WANT and I tried to change html in echo in my PHP code but I can't get the result at all and the shape of the table is far away from what I want and this is the full script of my page .

答:
Like everyone else said, you should convert your horizontal array into a vertical one.

Of course it should be a universal function to convert any query result, as opposed to hardcoding the row headings. The idea is to get each row's array keys and use them as the keys for the new array and then add each corresponding value to the new array item.

Here is how it's done in mysqli:

```<code><?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = mysqli_connect('127.0.0.1','root','','test');
$mysqli->query("set names 'UTF8'");

$data = [];
$res = $mysqli->query("SELECT Name, Age, Height FROM student order by Name desc");
while ($row = $res->fetch_assoc()) {
    foreach(array_keys($row) as $key) {
        $data[$key][] = $row[$key];
    }
}
</code>```

and then you get an array with desired structure which you can output using the code from ROOT's answer:

```<code><table border="1">
  <?php foreach($data as $key => $val): ?>
    <tr>
      <td><?= $key ?></td>
      <?php foreach($val as $field): ?>
        <td><?= $field ?></td>
      <?php endforeach ?>
    </tr>
  <?php endforeach ?>
</table>
</code>```

Title: How to turn a table vertical using PHP

Body:
I am just learning PHP ,and I want to create a table that display echo data that I submit to my database , the problem I have that the table displayed horizontally by default as you see Horizontal default table this my script

Name
Age
Height

<?php
$conn = mysqli_connect("localhost", "root", "", "class");
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT Name, Age, Height FROM student order by Name desc";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "
" . $row["Name"]. "	" . $row["Age"] . "	"
. $row["Height"]. "
";
}
echo "
";
} else //{ echo "0 results"; }//
$conn->close();
?>

but I want it to be echoed vertically instead like this VERTICAL RESULT I WANT and I tried to change html in echo in my PHP code but I can't get the result at all and the shape of the table is far away from what I want and this is the full script of my page .

Body:
Like everyone else said, you should convert your horizontal array into a vertical one.

Of course it should be a universal function to convert any query result, as opposed to hardcoding the row headings. The idea is to get each row's array keys and use them as the keys for the new array and then add each corresponding value to the new array item.

Here is how it's done in mysqli:

<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = mysqli_connect('127.0.0.1','root','','test');
$mysqli->query("set names 'UTF8'");

$data = [];
$res = $mysqli->query("SELECT Name, Age, Height FROM student order by Name desc");
while ($row = $res->fetch_assoc()) {
    foreach(array_keys($row) as $key) {
        $data[$key][] = $row[$key];
    }
}

and then you get an array with desired structure which you can output using the code from ROOT's answer:

<table border="1">
  <?php foreach($data as $key => $val): ?>
    <tr>
      <td><?= $key ?></td>
      <?php foreach($val as $field): ?>
        <td><?= $field ?></td>
      <?php endforeach ?>
    </tr>
  <?php endforeach ?>
</table>