Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: Interlineaarigeneraattori

Sivun loppuun

kuukkelinkutittelija [27.07.2020 20:25:32]

#

Ohjelma tekee automaattisesti interlineaareja, siis muutaman sanan pituisia käännöksiä ja alkutekstiä limittäin sisältäviä tekstitiedostoja. Tekstit ovat erittäin tehokas apuväline uuden kielen opiskeluun esimerkiksi @Voice-puhesyntetisaattorisovelluksella luettuina (Android). Kannattaa ajaa omalla palvelimella, esim. XAMPP. Ohjelma käyttää Google Kääntäjä -palvelua, joka sisältää rajoituksia palvelinpyyntöjen määrälle per IP-osoite, joten käännettävän tekstin pituus on rajattava kerralla käännettävän kokonaisuuden pituus x 100 sanaan.

Käännökset ovat laadukkaampia, jos käytetään sarja per sarja -käännöstapaa ja pitkää sarjaa. Sana per sana -käännöstavan ja lyhyen sarjan etuna on, ettei voi mennä sekaisin mikä alkutekstin sana vastaa mitäkin käännöksen sanaa, mutta sanojen monimerkityksisyyden ja kielten rakenne-erojen takia osasta käännöstä voi tulla sekava (opettaa vain irrallisia sanoja). Sana per sana -toiminto onkin hyödyllinen täysin vieraan kielen opiskelun alkuvaiheessa, sarja per sarja -toiminto sitten kun opiskelussa on jonkin verran edistytty. Täytyy muistaa, että konekäännökset sisältävät virheitä etenkin kieliperheestä toiseen käännettäessä, vaikka teknologia on kehittynyt nopeasti.

Tarvittava laajennus: https://github.com/Stichoza/google-translate-php

<?php

// index.php

// Laajennuksen asetus, tarkista että kansio on oikea.
require 'vendor/autoload.php';

use Stichoza\GoogleTranslate\GoogleTranslate;

// Jos syötetty lomake, niin käännöstyö, muuten näytetään lomake.
if(isset($_POST['jumpsize'])) {

	// Raakateksti output
	header("Content-Type: text/plain");

	// Syötteet muuttujiin
	$jumpsize = $_POST['jumpsize'];	// Sarjan pituus, monenko sanan palasiin teksti jaotellaan
	$erotin1 = $_POST['erotin1'];	// Sarjan jakomerkki, oletuksena tuplarivinvaihto
	$erotin2 = $_POST['erotin2'];	// Sarjan loppumerkki, oletuksena tuplarivinvaihto
	$teksti = $_POST['teksti'];		// Teksti josta generoidaan interlineaari
	$srclang = $_POST['srclang'];	// Lähdekieli, Google Kääntäjän ymmärtämä lyhenne
	$trglang = $_POST['trglang'];	// Kohdekieli

	// sanapersana = jokainen sana käännetään erikseen, sanajärjestys siis pysyy
	// sarjapersarja = muutaman sanan sarja käännetään kokonaisuutena
	$sanavaisarja = $_POST['sanavaisarja'];

	/* Laajennuksen asetus ja lähde- ja kohdekielet */
	$tr = new GoogleTranslate();
	$tr->setSource($srclang);
	$tr->setTarget($trglang);

	// Rivinvaihdot välilyönneiksi
	$teksti = str_replace("\r\n", " ", $teksti);
	$teksti = str_replace("\r", " ", $teksti);
	$teksti = str_replace("\n", " ", $teksti);
	while (strpos($teksti, "  ") !== false)
	{
		$teksti = str_replace("  ", " ", $teksti);
	}

	// Teksti taulukoksi sana per sana
	$tekstiarray = explode(' ', $teksti);

	if ($sanavaisarja == 'sanapersana') {

		// Sana per sana -interlineaarin luonti
		for ($i = 0; $i < sizeof($tekstiarray); $i = $i + $jumpsize)
		{
			// Käännetään käyttäjän asettama määrä sanoja yksi kerrallaan ja tulostetaan
			for ($i2 = 0; $i2 < $jumpsize; $i2++)
			{

				if($i+$i2 == sizeof($tekstiarray))
					break;
				$tmptrans = $tekstiarray[$i+$i2];
				echo $tr->translate($tmptrans).' ';
			}
			echo $erotin1; // Välimerkki

			// Tulostetaan alkutekstistä edellä käännetty kohta muuttumattomana
			for ($i2 = 0; $i2 < $jumpsize; $i2++)
			{
				if($i+$i2 == sizeof($tekstiarray))
					break;
				$tmptrans = $tekstiarray[$i+$i2];
				echo $tmptrans.' ';
			}
			echo $erotin2; // Loppumerkki
		}
	}
	else
	{
		// Sarja per sarja
		for ($i = 0; $i < sizeof($tekstiarray); $i = $i + $jumpsize)
		{
			// Tulostetaan käännös koko sarjalle
			$tmptrans = '';
			for ($i2 = 0; $i2 < $jumpsize; $i2++)
			{

				if($i+$i2 == sizeof($tekstiarray))
					break;
				$tmptrans = $tmptrans.str_replace(array("\r", "\n"), " ", $tekstiarray[$i+$i2]).' ';

			}
			echo $tr->translate($tmptrans).' ';
			echo $erotin1; // Välimerkki

			// Tulostetaan alkuteksti muuttumattomana
			echo $tmptrans.' ';
			echo $erotin2; // Loppumerkki
		}
	}
}
else
{
	// Lomakkeen tulostus jos ei ole lähetetty mitään
	echo "<!DOCTYPE html><html><body><form method='post' action='index.php'>

	Lähdekieli: <input type='text' name='srclang' value='af' /><br />
	Kohdekieli: <input type='text' name='trglang' value='en' /><br />
	Sarjan pituus: <input type='text' name='jumpsize' value='10' /><br />
	Erotin 1: <textarea name='erotin1'>\n\n\n</textarea><br />
	Erotin 2: <textarea name='erotin2'>\n\n\n</textarea><br />
	Käännettävä kokonaisuus: <select name='sanavaisarja'>
	  <option value='sarjapersarja'>Sarja per sarja</option>
      <option value='sanapersana'>Sana per sana</option>
    </select><br />
	Teksti (max kerralla käännettävä sanamäärä x 100 sanaa):<br /><textarea name='teksti' cols='25' rows='10'></textarea><br />

	<input type='submit' value='Interlineaari'></form></body></html>";
}

?>

The Alchemist [29.07.2020 06:36:50]

#

Kannattaisi siivota koodi ennen sen julkaisua. Nyt esimerkiksi rivejä ja lohkoja on sisennetty täysin sattumanvaraisesti.

Älä tulosta HTML:ää echolla vaan tee se kokonaan PHP-koodin ulkopuolella.

<?php

$foo = foo();
$bar = bar();

?>
<!DOCTYPE html>
<html>
....
  <p><?= $foo ?></p>
  <p><?= $bar ?></p>
...
</html>

Kolmannen osapuolen kirjastoista riippuvainen koodi olisi parempi julkaista kokonaisena; laita siis composer.json mukaan, jotta voimme asentaa koko projektin automaattisesti ja oikeilla riippuvuuksien versioilla.

Oikeastaan ihan paras olisi, että julkaiset oman koodisi Githubissa omassa repossaan ja lisäät senkin composer.jsoniin, jolloin käyttäjille riittää pelkän composer.json-tiedoston lataaminen.

Käännösten cachetus olisi varmaan paikallaan, koska muuten käyttäjä herkästi hankkii itsensä banniin Google Translatessa.

kuukkelinkutittelija [29.07.2020 21:55:09]

#

Meinaatko käännösten cachetuksella että usein esiintyvät sanat tallennettaisiin johonkin tiedostoon eikä niistä tarvitsisi tehdä uusia pyyntöjä? Google Translate antaa lyhyen automaattibännin 100 pyynnön jälkeen ja herjaa too many requests.

Voin siistiä sisennyksiä ja säätää nuo pari juttua jossain vaiheessa. Tulosteeseen ei sisälly html:ää ollenkaan joten en tiedä miten lomakkeen voi olla tulostamatta echolla. Koitin pitää mahdollisimman simppelinä ettei tule monta tiedostoa vaan lelu on nopeasti esim opiskelijan käytössä.

Metabolix [29.07.2020 22:18:42]

#

Pyyntöjä voisi vähentää sillä, että kaikki sanat kääntäisi kerralla. Ilmeisesti esimerkiksi numerointi säilyy kohdallaan käännöksessä: "(1) tämä (2) on (3) testi" => "(1) this (2) is (3) a test".

Juuri edellä näytetään, miten sen sivun voi tulostaa ilman echoa: laita PHP-tagi kiinni ?>:lla, niin tulostus alkaa. Tämän voi tehdä myös else-lohkon sisällä tai missä tahansa.

Funktioilla voi jäsentää ja selventää koodia:

<?php
// require jne.

function hoida_POST() {
  // Tänne POSTin käsittely.
}

// Itse sivu tiivistyy:
if (!empty($_POST)) {
  hoida_POST();
  exit();
}
?>
<!DOCTYPE html>
...

Lomakkeeseen voisi olla viisasta laittaa vaikka action="?post" (eikä index.php), jotta tiedostonimellä ei olisi merkitystä ja toisaalta lähetyksen jälkeinen ja edeltävä osoite eroaisivat toisistaan eli mm. selaimen takaisin-painike toimisi kivasti.

Fetch API:lla saa helposti muutettua sivun JavaScript-käyttöiseksi.

kuukkelinkutittelija [29.07.2020 23:08:16]

#

Kaikki sanat käännetään kerralla jos valitsee sarja per sarja -käännöstavan. Kaikissa kielissä tai lauseissa sanajärjestys ei säily jo ihan siitäkin syystä, että kaikki kielet eivät ole SVO-kieliä. Sana per sana -toiminto on hyvä pitää mahdollisena valita, jotta aloitteleva opiskelija voi varmistua ettei luule käännöksen sanaa 1 alkutekstin sanaksi 2.

walkout_ [30.07.2020 20:03:38]

#

HTML-koodin ja PHP-koodin erottamien olisi järkevää, koska sitä on kivempi sillloin katsoa WWW-selaimen kautta. Muuten jodun tekeen paljon lisätyötä pistämällä echon nk. plain/text-tiedoston rivinvahtoja ja muuta sellaista, että HTML-koodi näkyy selaimella katsottuna rivinvaihtojen ja sisennysten kanssa, jolloin sitä on helpompi lukea.

Koodin sisenteleyyn muuten löytyy sitten netistä automaatisia palveluita niin ei tarvitse välttämättä asennella esim. jotain PHP Eclipse. Ja nämä palvelut myös kommentoi koodia siltäossin missä joku if-lauseke alkaa ja missä kohtaa se päätyy, yms. yms.

kuukkelinkutittelija [30.07.2020 21:01:29]

#

Ainiin tosiaan, laitoin headeriksi plain text ettei tarvi kaivaa selaimen lähdekoodista rivinvaihdot näyttävää versiota. Teen noille vähän isommille pyydetyille muutoksille varmaan uuteen viestiin lopullisen version koodista sitten kun kerkiän ja tiedän mitä tarkalleen olen tekemässä...

walkout_ [30.07.2020 21:17:41]

#

kuukkelinkutittelija kirjoitti:

(30.07.2020 21:01:29): Ainiin tosiaan, laitoin headeriksi plain text...

Ei olisi tarvinnut laittaa kyllä headeriksi text/plain tai mitään muutakaan muuta kuin silloin kun haluat sekoittaa PHP/JavaScript-koodia, jne. Silloin esim. headerksi text/javascript

Jos välttämättä haluat tehdä pelkkää PHP-koodia ja echottaa HTML-koodia siihen niin homma onnistuu kyllä alla olvalla tavalla ilman, että tarvitsee laittaa \r\n Windows/Linux-rivinvaihhtoja tai vain Linuxin vastaavaa pelkästään. Jos käytät meinaan normaali ""-merkkejä echossa niin silloin tarvitsee laittaa rivinvahdot erikseen, jotka eivät taas näy käyttäjälle.

echo '<!DOCTYPE html>
<html>
   <body>
   </body>
<html>';

The Alchemist [02.08.2020 18:02:21]

#

kuukkelinkutittelija kirjoitti:

Tulosteeseen ei sisälly html:ää ollenkaan joten en tiedä miten lomakkeen voi olla tulostamatta echolla.

Juurihan laitoin sinulle esimerkin; katso siitä.

kuukkelinkutittelija kirjoitti:

Koitin pitää mahdollisimman simppelinä ettei tule monta tiedostoa vaan lelu on nopeasti esim opiskelijan käytössä.

Ruman ja huonon koodin tekeminen ei auta tässä asiassa yhtään mitään. Siistin ja järkevän koodin tekeminen auttaa.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta