Asked  7 Months ago    Answers:  5   Viewed   37 times

I'm reading an ebook on PHP right now, and the author noted that the difference between a while loop and a for loop is that the for loop will count how many times it runs.

So take this:

<?php
    for ($i = 1; $i < 10; $i = $i + 1) {
        print "Number $in";
    }
?> 

But wouldn't this be the same as

<?php
    $i = 1;
        while ($i < 10) {
            $i = $i + 1;
            print "Number $in";
        }
?>

Or is there some other differences that he didn't point out? (Aside from using while loop for when you're unsure of how long the condition will remain true, such as selecting rows from a database)

I mean, if that's the only difference, can't I just not use the for loop and use the while loop instead?

 Answers

30

Can you? Yes, certainly. But whether or not you should is an entirely different question.

The for loop is more readable in this scenario, and is definitely the convention you'll find used within virtually every language that has looping directives. If you use the while loop, people are going to wonder why you didn't use a for loop.

Wednesday, March 31, 2021
 
rob_mccann
answered 7 Months ago
48

You can use the strtr() function in PHP to pass in a key => value pair of replacement rules:

$data = mysql_query('SELECT * FROM todolist WHERE date > CURDATE()') or die(mysql_error());

// Array of replacement rules. Keys of the array are strings to be replaced.
// Corresponding values of the keys are the replacement strings
$trans = array(
    'stringtoreplace1' => 'replacedstring1',
    'stringtoreplace2' => 'replacedstring2',
    'stringtoreplace3' => 'replacedstring3'
);

while($info = mysql_fetch_array($data)) 
{
    print strtr($info['thingtobedone'], $trans) . ' with ' . $info['persontomeet'] . '<br />';
}

Assuming thingtobedone is the column you want to make the replacements on.

Then when you call strtr($info['thingtobedone'], $trans), the function will take the string and replace all occurances of every key value in the $trans array with their corresponding values. It's a nice way to make many string-replacements all at once.

Wednesday, March 31, 2021
 
waylaidwanderer
answered 7 Months ago
13

From Item 46 in Effective Java by Joshua Bloch :

The for-each loop, introduced in release 1.5, gets rid of the clutter and the opportunity for error by hiding the iterator or index variable completely. The resulting idiom applies equally to collections and arrays:

// The preferred idiom for iterating over collections and arrays
for (Element e : elements) {
    doSomething(e);
}

When you see the colon (:), read it as “in.” Thus, the loop above reads as “for each element e in elements.” Note that there is no performance penalty for using the for-each loop, even for arrays. In fact, it may offer a slight performance advantage over an ordinary for loop in some circumstances, as it computes the limit of the array index only once. While you can do this by hand (Item 45), programmers don’t always do so.

Tuesday, June 1, 2021
 
jerrygarciuh
answered 5 Months ago
80

Why not do the following? This will open it and close it after the third post. Then close the ending div in the event there is not a multiple of 3 to display.

$i = 1;
//added before to ensure it gets opened
echo '<div>';
if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post();
     // post stuff...

     // if multiple of 3 close div and open a new div
     if($i % 3 == 0) {echo '</div><div>';}

$i++; endwhile; endif;
//make sure open div is closed
echo '</div>';

In case you didn't know, % is the modus operator will return the remainder after the two numbers are divided.

Monday, July 12, 2021
 
mnagel
answered 3 Months ago
45

Well, there's essentially two questions here:

  1. What is the difference (in general) between one to one, many to many, and foreign key relations
  2. What are their differences specific to Django.

Both of these questions are quite easily answered through a simple Google search, but as I cannot find an exact dupe of this question on SO, I'll go ahead and answer.

Note that in Django, relationships should only be defined on one side of the relationship.


ForeignKey

A foreign key relationship is generally known as a many-to-one relationship. Note that the reverse of this relationship is one-to-many (which Django provides tools to access). As the name implies, many objects may be related to one.

Person >--| Birthplace
   ^           ^
   |           |
  Many        One 

In this example, a person may only have one birthplace, but a birthplace may be related to many people. Let's look at this example in Django. Say these are our models:

class Birthplace(models.Model):
    city = models.CharField(max_length=75)
    state = models.CharField(max_length=25)

    def __unicode__(self):
        return "".join(self.city, ", ", self.state)

class Person(models.Model):
    name = models.CharField(max_length=50)
    birthplace = models.ForeignKey(Birthplace)

    def __unicode__(self):
        return self.name

You can see that no relations are defined within the Birthplace model, and a ForeignKey relationship is defined within the Person model. Say that we create the following instances of our models (obviously not in Python syntax):

  • Birthplace: Dallas, Texas
  • Birthplace: New York City, New York
  • Person: John Smith, Birthplace : (Dallas, Texas)
  • Person: Maria Lee, Birthplace : (Dallas, Texas)
  • Person: Daniel Lee, Birthplace : (New York City, New York)

Now we can see how Django lets us use these relations (note that ./manage.py shell is your friend!):

>> from somewhere.models import Birthplace, Person
>> Person.objects.all()
[<Person: John Smith>, <Person: Maria Lee>, <Person: Daniel Lee>]
>> Birthplace.objects.all()
[<Birthplace: Dallas, Texas>, <Birthplace: New York City, New York>]

You can see the model instances we created. Now let's checkout someone's birthplace:

>> person = Person.object.get(name="John Smith")
>> person.birthplace
<Birthplace: Dallas, Texas>
>> person.birthplace.city
Dallas

Let's say you want to see all people with a given birthplace. As I said earlier, Django allows you to access reverse relations. By default, Django creates a manager (RelatedManager) on your model to handle this, named <model>_set, where <model> is your model name in lowercase.

>> place = Birthplace.objects.get(city="Dallas")
>> place.person_set.all()
[<Person: John Smith>, <Person: Maria Lee>]

Note that we can change the name of this manager by setting the related_name keyword argument in our model relation. So, we would change the birthplace field in the Person model to:

birthplace = models.ForeignKey(Birthplace, related_name="people")

Now, we can access that reverse relationship with a pretty name:

>> place.people.all()
[<Person: John Smith>, <Person: Maria Lee>]

One-to-one

A one-to-one relationship is quite similar to a many-to-one relationship, except that it restricts two objects to having a unique relationship. An example of this would be a User and a Profile (which stores information about the user). No two users share the same profile.

User |--| Profile
  ^          ^
  |          |
 One        One

Let's look at this in Django. I won't bother to define the user model, as Django defines it for us. Do note, however, that Django suggests using django.contrib.auth.get_user_model() to import the user, so that's what we'll do. The profile model may be defined as follows:

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL) # Note that Django suggests getting the User from the settings for relationship definitions
    fruit = models.CharField(max_length=50, help_text="Favorite Fruit")
    facebook = models.CharField(max_length=100, help_text="Facebook Username")

    def __unicode__(self):
        return "".join(self.fruit, " ", self.facebook)

All we need is one user with a profile to test this out in the shell:

  • User: johndt6
  • Profile: user : johndt6, "Kiwi", "blah_blah"

Now you may easily access the user's profile from the User model:

>> user = User.objects.all()[0]
>> user.username
johndt6
>> user.profile
<Profile: Kiwi blah_blah>
>> user.profile.fruit
Kiwi
>> profile = Profile.objects.get(user=user)
>> profile.user
<User: johndt6>

Of course, you may customize the name of the reverse relation using the related_name argument as above.


Many-to-many

Many-to-many relationships can be a bit tricky. Let me start by saying that many-to-many fields are messy, and should be avoided when possible. Given that, there are plenty of situations where a many-to-many relationship makes sense.

A many-to-many relationship between two models defines that zero, one or more objects of the first model may be related to zero, one or more objects of the second model. As an example, let's envision a company that defines their workflow through projects. A project may be related to no orders, only one order, or many orders. An order may be related to no projects, one project, or many.

Order >--< Project
  ^           ^
  |           |
 Many        Many

Let's define our models as so:

class Order(models.Model):
    product = models.CharField(max_length=150)  # Note that in reality, this would probably be better served by a Product model
    customer = models.CharField(max_length=150)  # The same may be said for customers

    def __unicode__(self):
        return "".join(self.product, " for ", self.customer)

class Project(models.Model):
    orders = models.ManyToManyField(Order)

    def __unicode__(self):
        return "".join("Project ", str(self.id))

Note that Django will create a RelatedManager for the orders field to access the many-to-many relationship.

Let's create the following instances of our models (in my inconsistent syntax!):

  • Order: "Spaceship", "NASA"
  • Order: "Submarine", "US Navy"
  • Order: "Race car", "NASCAR"
  • Project: orders: []
  • Project: orders: [(Order: "Spaceship", "NASA")]
  • Project: orders: [(Order: "Spaceship", "NASA"), (Order: "Race car", "NASCAR")]

We can access these relationships as follows:

>> Project.objects.all()
[<Project: Project 0>, <Project: Project 1>, <Project: Project 2>]
>> for proj in Project.objects.all():
..     print(proj)
..     proj.orders.all()  # Note that we must access the `orders`
..                        # field through its manager
..     print("")
Project 0
[]

Project 1
[<Order: Spaceship for NASA>]

Project 2
[<Order: Spaceship for NASA>, <Order: Race car for NASCAR>]

Note that the NASA order is related to 2 projects, and the US Navy order is related to none. Also note that one project has no orders, and one has multiple.

We may also access the relationship in reverse in the same way we have before:

>> order = Order.objects.filter(customer="NASA")[0]
>> order.project_set.all()
[<Project: Project 0>, <Project: Project 2>]

ASCII Cardinality Guide

In the likely case that my ASCII diagrams are a bit confusing, the following explanations might be helpful:

  • > or < means "to many"
  • | means "to one"

So... A --| B means an instance of A can be related to only ONE instance of B.

And A --< B means an instance of A can be related to MANY instances of B.

A >--< B is equivalent to....

A --< B
A >-- B

Thus, each "side" or direction of the relationship can be read separately. It's just convenient to squish them together.

Expanding one of these relationships might make more sense:

               +---- John Smith
               |
 Dallas|-------+---- Jane Doe
               |
               +---- Joe Smoe

Resources

Good explanation of db relationships provided by @MarcB

Wikipedia page on Cardinality

Django Docs:

models.ForeignKey

models.OneToOneField

models.ManyToManyField

One-to-one Relationships

Many-to-many Relationships

Tuesday, July 27, 2021
 
MDDY
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :