كيفية إعادة كتابة رمز سطر واحد (أو رمز سطر أقل في سطر الأوامر) لهذا الرمز في بيرل؟

StackOverflow https://stackoverflow.com/questions/5402405

  •  28-10-2019
  •  | 
  •  

سؤال

لدي رمز مثل هذا:

#!/usr/bin/perl
use strict;
use warnings;      
my %proteins = qw/
    UUU F UUC F UUA L UUG L UCU S UCC S UCA S UCG S UAU Y UAC Y UGU C UGC C UGG W
    CUU L CUC L CUA L CUG L CCU P CCC P CCA P CCG P CAU H CAC H CAA Q CAG Q CGU R CGC R CGA R CGG R
    AUU I AUC I AUA I AUG M ACU T ACC T ACA T ACG T AAU N AAC N AAA K AAG K AGU S AGC S AGA R AGG R
    GUU V GUC V GUA V GUG V GCU A GCC A GCA A GCG A GAU D GAC D GAA E GAG E GGU G GGC G GGA G GGG G
    /;
open(INPUT,"<dna.txt");
while (<INPUT>) {    
    tr/[a,c,g,t]/[A,C,G,T]/;
    y/GCTA/CGAU/;    
    foreach my $protein (/(...)/g) {
        if (defined $proteins{$protein}) {
        print $proteins{$protein};
        }
}
}
close(INPUT);

يرتبط هذا الرمز بإجابة سؤالي الآخر: DNA إلى RNA والحصول على البروتينات باستخدام Perl

مخرجات البرنامج هي :

SIMQNISGREAT

كيف يمكنني إعادة كتابة هذا الرمز باستخدام Perl، وسيتم تشغيله في سطر الأوامر وسيتم إعادة كتابته باستخدام رمز أقل (إن أمكن، رمز سطر واحد)؟

ملاحظة 1: dna.txt يشبه هذا:

TCATAATACGTTTTGTATTCGCCAGCGCTTCGGTGT

ملاحظة 2: إذا كان الكود أقل سطرًا، فمن المقبول كتابة my %proteins متغير في ملف .

هل كانت مفيدة؟

المحلول

شخص ما (@kamaci) اتصل باسمي في موضوع آخر.هذا هو أفضل ما يمكنني التوصل إليه مع الاحتفاظ بجدول البروتين في سطر الأوامر:

perl -nE'say+map+substr("FYVDINLHL%VEMKLQL%VEIKLQFYVDINLHCSGASTRPWSGARTRP%SGARTRPCSGASTR",(s/GGG/GGC/i,vec($_,0,32)&101058048)%63,1),/.../g' dna.txt

(نقلاً عن Shell، بالنسبة لنظام التشغيل Windows، نقلاً عن المبادلة ' و " الشخصيات).يضع هذا الإصدار رموزًا غير صالحة بـ %, ، ربما يمكنك إصلاح ذلك عن طريق إضافة =~y/%//d في مكان مناسب.

تَلمِيح:يقوم هذا باختيار 6 بتات من ترميز ASCII الخام لثلاثية RNA، مما يعطي 64 رمزًا بين 0 و101058048؛للحصول على فهرس سلسلة، قمت بتقليل النتيجة modulo 63، ولكن هذا يخلق تعيينًا مزدوجًا واحدًا والذي كان عليه للأسف تشفير بروتينين مختلفين.ال s/GGG/GGC/i يعيّن أحدهما إلى الآخر الذي يرمز للبروتين الصحيح.

لاحظ أيضًا الأقواس قبل % المشغل الذي كلاهما عزل , عامل التشغيل من قائمة الوسائط الخاصة بـ substr و تحديد أسبقية & ضد %.إذا استخدمت ذلك في كود الإنتاج، فأنت شخص سيء وسيئ.

نصائح أخرى

التغييرات الوحيدة التي أوصي بإجرائها هي تبسيط ملفك while حلقة:

while (<INPUT>) {
    tr/acgt/ACGT/;
    tr/GCTA/CGAU/;
    foreach my $protein (/(...)/g) {
        if (defined $proteins{$protein}) {
            print $proteins{$protein};
        }
    }
}

منذ y و tr هي مترادفات، يجب عليك استخدام واحد منهم فقط.أظن tr يقرأ أفضل من y, ، لذلك اخترت tr.علاوة على ذلك، كنت تناديهم بشكل مختلف تمامًا، ولكن يجب أن يكون هذا هو نفس التأثير ويذكر فقط الحروف التي قمت بتغييرها بالفعل.(تم نقل جميع الشخصيات الأخرى إلى أنفسهم.هذا يجعلها كثيراً من الصعب رؤية ما يتم تغييره بالفعل.)

قد ترغب في إزالة open(INPUT,"<dna.txt"); والمقابلة close(INPUT); الخطوط، لأنها تجعل من الصعب جدًا استخدام برنامجك في خطوط أنابيب Shell أو مع ملفات إدخال مختلفة.ولكن الأمر متروك لك، إذا كان ملف الإدخال سيفعل ذلك دائماً يكون dna.txt ولا يوجد أي شيء مختلف أبدًا، فلا بأس.

#!/usr/bin/perl
%p=qw/UUU F UUC F UUA L UUG L UCU S UCC S UCA S UCG S UAU Y UAC Y UGU C UGC C UGG W
CUU L CUC L CUA L CUG L CCU P CCC P CCA P CCG P CAU H CAC H CAA Q CAG Q CGU R CGC R CGA R CGG R
AUU I AUC I AUA I AUG M ACU T ACC T ACA T ACG T AAU N AAC N AAA K AAG K AGU S AGC S AGA R AGG R
GUU V GUC V GUA V GUG V GCU A GCC A GCA A GCG A GAU D GAC D GAA E GAG E GGU G GGC G GGA G GGG G/;
$_=uc<DATA>;y/GCTA/CGAU/;map{print if$_=$p{$_}}/(...)/g
__DATA__
TCATAATACGTTTTGTATTCGCCAGCGCTTCGGTGT

أوف.أفضل ما يمكنني التوصل إليه، على الأقل بهذه السرعة.إذا كنت متأكدًا من أن الإدخال دائمًا مكتوب بأحرف كبيرة، فيمكنك أيضًا إسقاط uc إنقاذ حرفين آخرين.أو إذا كان الإدخال هو نفسه دائمًا، فيمكنك تعيينه إليه $_ على الفور بدلا من قراءتها من أي مكان.

أعتقد أنني لست بحاجة إلى أن أقول أن هذا الرمز ينبغي لا يمكن استخدامها في بيئات الإنتاج أو في أي مكان آخر غير المتعة الخالصة.عند القيام بالبرمجة الفعلية، غالبًا ما تفوز سهولة القراءة على الاكتناز.

بعض الإصدارات الأخرى التي ذكرتها في التعليقات:

قراءة %p والحمض النووي من الملفات:

#!/usr/bin/perl
open A,"<p.txt";map{map{/(...)/;$p{$1}=chop}/(... .)/g}<A>;
open B,"<dna.txt";$_=uc<B>;y/GCTA/CGAU/;map{print if$_=$p{$_}}/(...)/g

من القشرة مع perl -e:

perl -e 'open A,"<p.txt";map{map{/(...)/;$p{$1}=chop}/(... .)/g}<A>;open B,"<dna.txt";$_=uc<B>;y/GCTA/CGAU/;map{print if$_=$p{$_}}/(...)/g'

لقد تمت الإشارة إلى معظم الأشياء بالفعل، خاصة أن سهولة القراءة مهمة.لن أحاول تقليل البرنامج أكثر مما يلي.

use strict;
use warnings;
# http://stackoverflow.com/questions/5402405/
my $fnprot = shift || 'proteins.txt';
my $fndna  = shift || 'dna.txt';
# build protein table
open my $fhprot, '<', $fnprot or die "open $fnprot: $!";
my %proteins = split /\s+/, do { local $/; <$fhprot> };
close $fhprot;
# process dna data
my @result;
open my $fhdna, '<', $fndna or die "open $fndna: $!";
while (<$fhdna>) {
    tr/acgt/ACGT/;
    tr/GCTA/CGAU/;
    push @result, map $proteins{$_}, grep defined $proteins{$_}, m/(...)/g;
}
close $fhdna;
# check correctness of result (given input as per original post)
my $expected = 'SIMQNISGREAT';
my $got = join '', @result;
die "@result is not expected" if $got ne $expected;
print "@result - $got\n";

الشيء الوحيد الذي أضفته هو "الخط الواحد". push map grep m//g في الحلقة بينما.لاحظ أن Perl 5.10 يضيف عامل التشغيل "المحدد أو" - // - والذي يسمح لك بالكتابة:

push @result, map $proteins{$_} // (), m/(...)/g;

اه حسنا، open do local $/ تعتبر لغة file slurp مفيدة لنقل الملفات الصغيرة إلى الذاكرة.آمل أن تجد أنه ملهم بعض الشيء.:-)

في حالة كتابة بيانات البروتينات إلى ملف آخر، تكون المساحة محددة وبدون فواصل الأسطر.لذلك، يمكنك استيراد البيانات عن طريق قراءة الملف مرة واحدة.

#!/usr/bin/perl
use strict;
use warnings;      

open(INPUT, "<mydata.txt");
open(DATA, "<proteins.txt");
my %proteins = split(" ",<DATA>);

while (<INPUT>) {
    tr/GCTA/CGAU/;
    while(/(\w{3})/gi) {print $proteins{$1} if (exists($proteins{$1}))};
}
close(INPUT);
close(DATA);

يمكنك إزالة سطر من التعليمات البرمجية "ص / أ، ج، ز، ر / أ، ج، ز، تي /" لأن عامل المطابقة لديه خيار غير حساس لحالة الأحرف (أنا خيار).والأصلي com.foreach يمكن تحسين الحلقة مثل الكود أعلاه. $1 المتغير هنا هو نتيجة النمط المطابق داخل أقواس عملية المطابقة /(\ث{3})/gi

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top